#ifndef __BoardWork_C
#define __BoardWork_C

#include "BoardWork.h"

// 数据初始化
void data_init(){
	  #if I_rated_count > 1
			// 设置默认占空比
			I_rated_idx = 0;
			PWM_Data.ratedDuty = DUTY_CYCLE_List[I_rated_idx];
			#if meter485_ON > 0
			I_State_Flag.I_rated_value2 = I_rated_List2[I_rated_idx];
			#endif
			I_State_Flag.I_rated_value  = I_rated_List[I_rated_idx];
			I_State_Flag.I_rated_valuef = I_rated_Listf[I_rated_idx];
	  #else
			PWM_Data.ratedDuty = DUTY_CYCLE_default;
	    #if meter485_ON > 0
			I_State_Flag.I_rated_value2 = I_rated_default2;
			#endif	  
			I_State_Flag.I_rated_value = I_rated_default;	
			I_State_Flag.I_rated_valuef = I_rated_defaultf;
	  #endif	
    get_I_rated_value(); 
	
	  #ifdef Using_LedCtrl_74HC595
	  LedOff595_bits   = led595AllOff;
	  #endif
		
	  // 函数内获取时间戳
	  #if RTC_ON > 0
		getTimestampRTC();
		#endif		
		
		// CP初始化
    cp_data.CP_idChg_Tm  = system_time;		
	  #if AUTHEN_CE > 0
	  cp_data.cp_up_or_down = cp_Direc_Down;             
		#endif
		
		// 充电状态初始化
		chg_stage = CHG_IDLE;
	  
	  #if RlyAdh_Detect_type > 0		
    rlyAdh_ToZero_tm = 0;
    #endif
	  
		#if CC_Detect_type == 0
		plug_out_times = 0;
		#endif
		system_started = 0;
		
		tmpr_CtrData.tmrp_using_id = tmrp_using_boardIn; 
		
		// 传感器数据准备完毕
		#if UI_Meter_Method == Meter_GuageIC_RN8209
		UI_Data.meterReady = 0;
		#else
		UI_Data.meterReady = 1;
	  #endif
		#if meter485_ON > 0
		mt485_Data.meterReady = 0;
		#endif
		#if finger_sensor_type == Finger_HLK_ZW101_POLL
		fingerCtrl.finger_step = 1;
		#endif
		
	  // 恢复次数限制设置:
		//默认250次,属于无限恢复了。
    faultRecv_Limit_tms = 250; 
		
		#if Using_UART_LCD == LCD_4P3_UART 
	  lcdParam.timer_recoder[0] = lcdParam.RTC_data[6];
		lcdParam.timer_recoder[1] = lcdParam.RTC_data[5];
		lcdParam.timer_recoder[2] = lcdParam.RTC_data[4];
	  #endif

    #if Key1  > 0  
		// 按键1初始状态：
		//key1_param.keyLevel = key1InitLevel;
		key1_level = key1InitLevel;
		#endif
		
		#if BleWifi_type == BleWifi_Ai_WB2
		bleWiFi_Data.bw_bleMode = -8;
		bleWiFi_Data.bw_wifiMode = -8;
		#endif
		
		// 串口参数初始化
		#if using_uart1 > 0
		uart1Ctrl.uart_idx = 0;
		#endif
		#if using_uart2 > 0
		uart2Ctrl.uart_idx = 0;
		#endif
		#if using_uart3 > 0
		uart3Ctrl.uart_idx = 0;
		#endif
		#if using_uart4 > 0
		uart4Ctrl.uart_idx = 0;
		#endif
		#if using_uart5 > 0
		uart5Ctrl.uart_idx = 0;
		#endif		
		plug_out_action();
		
}

// 插枪动作：
void plug_in_action(){
	  #ifdef SYS_DEBUG
	  printf("plug_in_action chgForbid = %d  \r\n",chgForbid);
	  #endif
	  // 记录起始电量
	  UI_Data.QOE_ChgStart = UI_Data.QOE;
	  #if  meter485_ON > 0
	  mt485_Data.QOE_ChgStart = mt485_Data.QOE;
	  #endif
	
	  // 自检数据初始化
	  #if CarD1_Protect > 0
			CarD1Param.CarD1_MarkNum   = 0;
			CarD1Param.CarD1_TestStart = 0;
			chg_selfCheck_complt = chg_selfCheck_complt & (~chg_selfCheck_CarD1);
	  #endif
	
	  // 插枪时间记录：
	  #if RTC_ON > 0
		getTimestampRTC();
		#endif
	  plugin_time = system_time;	  
}

// 拔枪后的任务：一般为某种状态恢复
void plug_out_action(){
	  #ifdef SYS_DEBUG
	  printf("plug_out_action chgForbid = %d  \r\n",chgForbid);
	  #endif
	  // 1. CP跳变次数请0
	  cp_data.CP_Jump_tms = 0;
	
    // 函数内获取时间戳
    #if RTC_ON > 0
		getTimestampRTC();
		#endif	
	  
	  // 恢复就直接刷新下变更时间;	  
		U_CtrData.Ustt_change_tm = system_time;	
	
	  // 保护恢复计数置0
	  faultOcc_IOvrRecv_counts = 0;
    faultOcc_TmprAdj_counts  = 0;
	
	  #ifndef UsingFreeRTOS
		fault_recover_tm = 0;	
    #endif  
	
	  // 充电数据初始化
		chg_start_tm  = 0;
		Rly_status = 0;
		I_CtrData.Istt_change_tm = 0;
		
		#if Has_RlyPin_Maintaining > 0
		Rly_startup_status = 0;	
		#endif
		
		#if PinPick_RatedI > 0
		PinPick_state = 0;
		#endif
		
		// 接地参数初始化：
		//PE_occ_times = 0;
		PE_occ_recode = system_time;
		
		// 漏电错误初始化：
		leakData.leak_tms = 0;
		
		// 充电禁止释放
	  chgForbid = 0;
								
	  // 拔枪后，错误码恢复
	  mTask_Fault        = 0;
		faultCode          = 0;
	  mTask_Fault_using  = 0;
    faultCodeUsingErr  = 0;
		faultCodeUsingLed  = 0;
				
    //刷新一下显示灯;		
    main_update = 1;  		
}

// 自检任务
void self_check(){
	  // 车载二极管自检项测试
	  #if CarD1_Protect > 0
	  #if RTC_ON > 0
		getTimestampRTC();
		#endif
	  if(CarD1Param.CarD1_TestStart > 0 && (system_time - CarD1Param.CarD1_TestStart > CarD1_Available_tm || CarD1Param.CarD1_MarkNum > CarD1_MarkNum_Avail)){
			  if(CarD1Param.CarD1_MarkNum > CarD1_MarkNum_Avail){
					  if(0 == (chg_selfCheck_complt & chg_selfCheck_CarD1)){
							  // 检测到0, 不分压，二极管无问题
								chg_selfCheck_complt = chg_selfCheck_complt | chg_selfCheck_CarD1;  // 自检无误;
								// 刷新并重新启动充电
								main_update = 1;
						}	
				} else {
					  // 二极管有问题：
					  if(cp_data.value_cope_id != CP_12){
								faultCode = carD1_bad;
								mTask_Fault = mTask_Fault | (0x0001 << (carD1_bad - 1));  //位置1	
                fault_update = 1;
						}	
				}
				#if CarD1_WholeLife_EN == 0
				  //停止车载二极管自检
					CarD1Param.CarD1_TestStart = 0;      								
					#if (CarD1_Detect_Tyte == CarD1_Detect_EINT)
						carD1_detect_stop();
					#endif
				#else
				   CarD1Param.CarD1_TestStart = system_time;
				   CarD1Param.CarD1_MarkNum   = 0;
        #endif				
		}
		
		// 重启自检		
		if(cp_data.value_cope_id != CP_12 && PWM_Data.pwmDuty > 50 && PWM_Data.pwmDuty < 950 && CarD1Param.CarD1_TestStart == 0){
			  if(0 == (chg_selfCheck_complt & chg_selfCheck_CarD1)){
			      // 车载二极管重启自检
						#if RTC_ON > 0
						//getTimestampRTC();
						#endif
						CarD1Param.CarD1_TestStart = system_time;
						CarD1Param.CarD1_MarkNum   = 0;
						#if CarD1_Detect_Tyte == CarD1_Detect_EINT
							carD1_detect_start();
						#endif
				} 
		}
		#endif	// #if CarD1_Protect > 0
		
    // 漏电自检信号
    #if (RCD_TYPE_B > 0) && (testSelfLeak > 0) && (leak_testSelf_get > 0)
    if(leakData.leak_test_init_step > 1 && leakData.leak_testSelf_occs > 0 && (0 == (chg_selfCheck_complt & chg_selfCheck_Leak))){
			  // 检测到自检信号：
			  chg_selfCheck_complt = chg_selfCheck_complt | chg_selfCheck_Leak;
			  // 刷新并重新启动充电
        main_update = 1;
		}
		// 重新自检:自检失败后，重新自检。
		#if RTC_ON > 0
		//getTimestampRTC();
		#endif
    #if testSelfLeak == Leak_RCPD_08BS75_2P2 || testSelfLeak == UIFG_R10x_3A		
		if(cp_data.value_cope_id > CP_0 && (leakData.leak_test_init_step == 3 || leakData.leak_test_init_step == 0) && (0 == (chg_selfCheck_complt & chg_selfCheck_Leak)) && (system_time - leakData.leakSelfTest_start_tm) > leak_stepLast_tm){
    #elif testSelfLeak == Leak_FM2161A
    if(cp_data.value_cope_id > CP_0 && (leakData.leak_test_init_step == 5 || leakData.leak_test_init_step == 0) && (0 == (chg_selfCheck_complt & chg_selfCheck_Leak)) && (system_time - leakData.leakSelfTest_start_tm) > leak_stepLast_tm){		
    #endif		
				#ifndef UsingFreeRTOS
				leakData.leak_test_init_step = 1;
				#endif	
        #if RTC_ON > 0
				//getTimestampRTC();
				#endif		  
				leakData.leakSelfTest_start_tm = system_time;
			  leakData.leak_testSelf_occs = 0;
		}
		#endif	
    
}
	
// 处理rom数据：
void assign_flash_data(){	
	  #if I_rated_count > 1 && Rated_Save_EN > 0
    uint8_t i = 0;  
	  #endif
	  #if I_rated_count > 1 && Rated_Save_EN > 0
	  // 读取占空比数据
	  for(i = 0; i < I_rated_count; i++){
	      if(isFloatSame(writeData[FWD_IRated_idx].intData,I_rated_List[i])){
						 I_rated_idx = i;
             #if meter485_ON > 0
						 I_State_Flag.I_rated_value2 = I_rated_List2[I_rated_idx];
						 #endif
						 I_State_Flag.I_rated_value  = I_rated_List[I_rated_idx];	
						 I_State_Flag.I_rated_valuef = I_rated_Listf[I_rated_idx];	
						 PWM_Data.ratedDuty = DUTY_CYCLE_List[I_rated_idx];    
						 break;
				}
		}
		#endif
	  #if Rated_Save_EN > 0
		get_I_rated_value();
	  #endif
	
		// 读取充电桩的id	
    if(writeData[Chgr_Id_Int_H].intData != 0xffffffff && writeData[Chgr_Id_Int_L].intData != 0xffffffff){
			  Chgr_Name[0] = writeData[Chgr_Id_Int_H].charData[0];
				Chgr_Name[1] = writeData[Chgr_Id_Int_H].charData[1];
				Chgr_Name[2] = writeData[Chgr_Id_Int_H].charData[2];
				Chgr_Name[3] = writeData[Chgr_Id_Int_H].charData[3];
				Chgr_Name[4] = writeData[Chgr_Id_Int_L].charData[0];
				Chgr_Name[5] = writeData[Chgr_Id_Int_L].charData[1];
				Chgr_Name[6] = writeData[Chgr_Id_Int_L].charData[2];
				Chgr_Name[7] = writeData[Chgr_Id_Int_L].charData[3];	
		} else {
			  sprintf(Chgr_Name, "%08X", MCU_ID_1);			  
		}
		printf("name: %s \r\n",Chgr_Name);
		// 读取系统启动次数数据
		system_startup_times = writeData[FWD_SysStart_idx].intData;		
    system_startup_times++;
		writeData[FWD_SysStart_idx].intData = system_startup_times | 0x00000000;
    flash_write();
				
		// 打印输出
		#ifdef SYS_DEBUG
		printf("system start up times = %d  \n",system_startup_times);
		printf("charger id = %s  \n",Chgr_Name);
		#endif
    
		// 读取电量数据：
		#if (GET_K_Actv != 0)  || (Get_QOE_Method == Meter_SelfADC)
		UI_Data.QOE = writeData[FWD_QOE_idx].fltData;
		if(UI_Data.QOE >= 1000000 || UI_Data.QOE < 0){
			  UI_Data.QOE = 0;
		}		
    #endif	
		
		// 记录起始电量
	  UI_Data.QOE_ChgStart = UI_Data.QOE;
		#if  meter485_ON > 0
	  mt485_Data.QOE_ChgStart = mt485_Data.QOE;
	  #endif
		
		// 读取预约充电数据：24字节
		#if RESV_CHG_ON  > 0 || PlugCharge_And_Resv
		resv_data.resv_start_point = ((uint64_t)writeData[resv_sp_idxH].intData << 32) + writeData[resv_sp_idxL].intData;
		resv_data.resv_time[0] = (uint16_t)(writeData[resv_t1_idx].intData >> 16);
		resv_data.resv_time[1] = (uint16_t)(writeData[resv_t1_idx].intData & 0x0000ffff);
		resv_data.resv_time[2] = (uint16_t)(writeData[resv_t2_idx].intData >> 16);
		resv_data.resv_time[3] = (uint16_t)(writeData[resv_t2_idx].intData & 0x0000ffff);
		resv_data.resv_week.week = writeData[resv_wkEn_idx].charData[0];
		
		resv_data.resv_start_point = 0;
		resv_data.resv_time[0] = 0;
		resv_data.resv_time[1] = 0;
		resv_data.resv_time_idx = 0;
		#endif
		
		// 读取log总数数据：
		#if LOG_ON > 0
			Log_Saved_Sum = (uint16_t)writeData[FWD_LogsSize_idx].intData;
			if(Log_Saved_Sum > Logs_Data_size){
					Log_Saved_Sum = 0;
			}
			printf(" Log_Saved_Sum = %d  \r\n",Log_Saved_Sum);
			#if Nor_Flash > 0 
				// 保存到外部flash的页数
				log_sect_save_id = (uint16_t)writeData[FWD_LogSavePageId_idx].intData;
				if(log_sect_save_id > Total_LogData_Sects){
						log_sect_save_id = 0;
				} 
				log_sect_read_id = log_sect_save_id;
				printf(" log_page_read_id = %d  \r\n",log_sect_read_id);
			#endif // #if Nor_Flash > 0
		#endif // #if LOG_ON > 0
		
		// 读取功率曲线数据的参数
		#if CURVE_ON > 0
			Curv_Saved_Sum = (uint16_t)writeData[FWD_CurvSize_idx].intData;
			if(Curv_Saved_Sum > Curv_Data_size){
					Curv_Saved_Sum = 0;
			}
			printf(" Curv_Saved_Sum = %d  \r\n",Curv_Saved_Sum);
			#if Nor_Flash > 0 
				// 保存到外部flash的页数
				curv_sect_save_id = (uint16_t)writeData[FWD_CurvSavePageId_idx].intData;
				if(curv_sect_save_id > Total_CurvData_Sects){
						curv_sect_save_id = 0;
				} 
				curv_sect_read_id = curv_sect_save_id;
				printf(" curv_page_read_id = %d  \r\n",curv_sect_read_id);
			#endif // #if Nor_Flash > 0
		#endif // #if LOG_ON > 0
		
		// 主策略刷新下
		main_update++;
}

#if Using_UART_LCD == LCD_0P42_IIC
// 获取显示数据：
void getShowData(){
	  int8_t x_offset = OLED_SEG_start;
	  #ifdef SSD1315
	  int8_t y_offset = 0; 
	  #else
	  int8_t y_offset = -1;
	  #endif
	  uint16_t i = 0;
	  char showDatas[9] = {' '};		
		if(cp_data.value_cope_id == CP_6){
			  if(dataId >= 3 * refreshOledDataFreq){
						dataId = 0;
				}			  
		} else {
			  dataId = 0;
		}		
		// 清屏
		for(i = 0; i < 1024; i++){
			  oledAllDotShow[i] = 0x00;
		}		
    // 装数据	
	  if(dataId / refreshOledDataFreq == 0){
			  if(cp_data.value_cope_id == CP_6){
					  uint8_t j = 0;
						for(j = 0; j < 4; j++){
								for(i = 0; i < 21; i++){
										oledAllDotShow[i + x_offset + (j + y_offset + 2) * 128] = battery_icon[j][i]; 
								}
						}
						// 插入电流说明
						sprintf(showDatas,"%4.1fA",UI_Data.I_RMS);
						insertOneString(x_offset + 26 ,y_offset + 3 ,showDatas,5);						
				} else {
				    uint8_t j = 0;
					  uint8_t I_rated_value_int = 0;
						for(j = 0; j < 4; j++){
								for(i = 0; i < 32; i++){
										oledAllDotShow[i + x_offset + (j + y_offset + 2) * 128] = chg_icon[j][i];
								}
						}						
						// 插入额定充电数据
						I_rated_value_int = (uint8_t)I_State_Flag.I_rated_valuef;
						sprintf(showDatas,"%2dA",I_rated_value_int);
						insertOneString2(x_offset + 26 ,y_offset + 2 ,showDatas,3);
				}		
		}
		#if GET_K_Actv != 0	|| (Get_QOE_Method == Meter_SelfADC)	
		else if(dataId / refreshOledDataFreq == 1){
        uint8_t  hh = 0;		
        uint8_t  mm = 0;
        uint8_t  ss = 0;
			  uint32_t chgnTms = 0;
        #if RTC_ON > 0
				getTimestampRTC();
				#endif				
        chgnTms = (uint32_t)((system_time - chg_start_tm) / 1000);
        ss = 	chgnTms % 60;
				mm =  chgnTms / 60 % 60;
				hh =  chgnTms / 3600 % 24;        				
			  sprintf(showDatas, "%5.1fKWh", (UI_Data.QOE - UI_Data.QOE_ChgStart) * 0.01);
			  insertOneString(26,y_offset + 1,showDatas,8);   //2
				sprintf(showDatas,"%02d:%02d:%02d",hh,mm,ss);
				insertOneString(28,y_offset + 3,showDatas,8);   //4
		}
		#endif
		else if(dataId / refreshOledDataFreq == 2){
				uint8_t j = 0;
				for(j = 0; j < 3; j++){
						for(i = 0; i < 24; i++){
								oledAllDotShow[i + x_offset + (j + y_offset + 2) * 128] = degree_celsius[j][i];  // F6x8[charId][i]
						}
				}
				// 插入温度说明
				//sprintf(showDatas,"%4.1f",TMP_BoardIn);
				sprintf(showDatas,"%4.1f",(float)(TMP_show_lb * 1.0 / 10));
				insertOneString(x_offset + 26 ,y_offset + 3 ,showDatas,4);
		}			
		dataId++;
		refreshOled();
}
#endif

#if (UI_Meter_Method == Meter_GuageIC_RN8209)   
void readUIValueFromGuage(){ 
	  uint8_t i = 0;	  
		// 检测是否需要校对:
		if(rnCheckSUMRead != rnCheckSUM){			  
				// 读取系统状态数据
				arrAllIs(0xff,rxDataBufSPI,SPI_DATA_SIZE);
				RN_ReadDatas(SysStatus,SysStatus_Len);	
				RN_Set_Regulation();
				// 读取新的检验和寄存器值
				arrAllIs(0xff,rxDataBufSPI,SPI_DATA_SIZE);
				RN_ReadDatas(EMUStatus,EMUStatus_Len);
				rnCheckSUMRead = 256 * rxDataBufSPI[1] + rxDataBufSPI[2];
				// 读取芯片编号：
				arrAllIs(0xff,rxDataBufSPI,SPI_DATA_SIZE);
				RN_ReadDatas(DeviceID,DeviceID_Len);
				for(i = 0; i < DeviceID_Len; i++){
						rnDeviceID[i] = rxDataBufSPI[i];
				}
				rnCheckTimes++;
				UI_Data.meterReady = 0;
		} else {			  
				// 读取电流有效值
        union dataFormatTrans	tmpData;		
			  float I_RMS_Tmp  = 0;  
			  float U_RMS_Tmp  = 0;  
			  float POWERA_Tmp = 0;  
				arrAllIs(0xff,rxDataBufSPI,SPI_DATA_SIZE);   
				RN_ReadDatas(IARMS,IARMS_Len);  
				if((rxDataBufSPI[0] & 0x80) == 0){
					  tmpData.int8DataArr[3] = 0x00;  
					  tmpData.int8DataArr[2] = rxDataBufSPI[0];  
					  tmpData.int8DataArr[1] = rxDataBufSPI[1];  
					  tmpData.int8DataArr[0] = rxDataBufSPI[2];  
					  uiValues.I_value = tmpData.int32Data;
						I_RMS_Tmp = uiValues.I_value * K_IRMS;  
				}										
				// 读取电压有效值
				arrAllIs(0xff,rxDataBufSPI,SPI_DATA_SIZE);   
				RN_ReadDatas(URMS,URMS_Len); 
				if((rxDataBufSPI[0] & 0x80) == 0){
					  tmpData.int8DataArr[3] = 0x00;
					  tmpData.int8DataArr[2] = rxDataBufSPI[0];
					  tmpData.int8DataArr[1] = rxDataBufSPI[1];
					  tmpData.int8DataArr[0] = rxDataBufSPI[2];
					  uiValues.U_value = tmpData.int32Data;
					  U_RMS_Tmp = uiValues.U_value * K_URMS; // tmpData * K_URMS;
				}		
				// 读取有功功率
				arrAllIs(0x00,rxDataBufSPI,SPI_DATA_SIZE); 
				RN_ReadDatas(PowerPA,PowerPA_Len); 
				tmpData.int8DataArr[3] = rxDataBufSPI[0];
				tmpData.int8DataArr[2] = rxDataBufSPI[1];
				tmpData.int8DataArr[1] = rxDataBufSPI[2];
				tmpData.int8DataArr[0] = rxDataBufSPI[3];
				POWERA_Tmp = tmpData.int32Data * K_POWERPA * (-1);
				// 读取无功功率
				arrAllIs(0xff,rxDataBufSPI,SPI_DATA_SIZE);
				RN_ReadDatas(PowerQ,PowerQ_Len);
				tmpData.int8DataArr[3] = rxDataBufSPI[0];
				tmpData.int8DataArr[2] = rxDataBufSPI[1];
				tmpData.int8DataArr[1] = rxDataBufSPI[2];
				tmpData.int8DataArr[0] = rxDataBufSPI[3];
        UI_Data.P_reactv = tmpData.int32Data;
				
        #if (Get_QOE_Method == Meter_GuageIC_RN8209)				
				// 读取有功电能
				arrAllIs(0xff,rxDataBufSPI,SPI_DATA_SIZE);  
				RN_ReadDatas(EnergyP,EnergyP_Len);  
        tmpData.int8DataArr[3] = 0x00;
				tmpData.int8DataArr[2] = rxDataBufSPI[0];  
				tmpData.int8DataArr[1] = rxDataBufSPI[1];  
				tmpData.int8DataArr[0] = rxDataBufSPI[2];
				// UI_Data.QOE = tmpData.uint32Data * K_EC - 0.0132206753442006;
				UI_Data.QOE = tmpData.uint32Data * K_EC;
				// 上电起始电量记录
				if(UI_Data.meterReady == 0 && UI_Data.QOE_ChgStart == 0){
					  UI_Data.QOE_ChgStart = UI_Data.QOE;
				}		
				
				// 读取无功电能
				arrAllIs(0xff,rxDataBufSPI,SPI_DATA_SIZE);  
				RN_ReadDatas(EnergyQ,EnergyQ_Len);
        tmpData.int8DataArr[3] = 0x00;
				tmpData.int8DataArr[2] = rxDataBufSPI[0];  
				tmpData.int8DataArr[1] = rxDataBufSPI[1];  
				tmpData.int8DataArr[0] = rxDataBufSPI[2];	
				UI_Data.QOE_reactv = tmpData.uint32Data * K_EC;
				// 读取事件标志：
				arrAllIs(0xff,rxDataBufSPI,SPI_DATA_SIZE);
				RN_ReadDatas(IF,IF_Len);
				if(((rxDataBufSPI[0] & (0x01 << 3)) == 0) && (rnIF & (0x01 << 3))){
						// 翻转过一次
						UI_Data.QOE_IFTimes++;
				}
				if(((rxDataBufSPI[0] & (0x01 << 3)) == 0) && (rnIF & (0x01 << 3))){
						// 翻转过一次
						UI_Data.QOE_reactv_IFTimes++;
				}
				rnIF = rxDataBufSPI[0];
				#endif
				
				// 验证数据有效性:
				if(fabs(I_RMS_Tmp * U_RMS_Tmp - POWERA_Tmp) < err_power){
					  UI_Data.I_RMS = I_RMS_Tmp; 
					  UI_Data.U_RMS = U_RMS_Tmp; 
					  UI_Data.P_actv = POWERA_Tmp;
            UI_Data.Papt   = UI_Data.P_actv; 	
            // printf(" %f  %f \r\n",UI_Data.Papt,UI_Data.P_actv);					
				}		
					
				UI_Data.meterReady = 1;				
		}
	  
}
#elif (UI_Meter_Method == Meter_GuageIC_RN8302B)   
void readUIValueFromGuage(){ 
		// 检测是否需要校对:
		if(rnDeviceID != IC_Device_ID && rnDeviceID != 0xffffffff && rnDeviceVerID != 0xffffffff){			  
				// 读取系统状态数据
				RN_Set_Regulation();
				// 读取芯片编号：
				rnDeviceID = RN_ReadDatas(DeviceID,DeviceID_Len); 
			  rnDeviceVerID = RN_ReadDatas(DeviceVer,DeviceVer_Len);		  
				rnCheckTimes++;
				UI_Data.meterReady = 0;
			
			  #ifdef SYS_DEBUG
        printf(" RN8302B Id is: 0x%08x ;   0x%08x \r\n",rnDeviceID,rnDeviceVerID);
			  if(rnDeviceVerID == IC_Device_V2){
					  printf(" Ver is V2 \r\n");
				} else if(rnDeviceVerID == IC_Device_V3){
					  printf(" Ver is V3 \r\n");
				}	else {
					  printf(" Ver is  other \r\n");
				}  
				#endif	
			
		} else {   
        // 能量数据
				// readDataTmp = RN_ReadDatas(EPT,EPT_Len);					
				// readDataTmp = RN_ReadDatas(PAFCnt,PAFCnt_Len);
				//readDataTmp = RN_ReadDatas(PTFCnt,PTFCnt_Len);
			  readDataTmp = RN_ReadDatas(EPT,EPT_Len);			  
			  if(readDataTmp != 0xffffffff) uiValues.QOE_value  = readDataTmp;
			  
				// 读取电流有效值
			  readDataTmp = RN_ReadDatas(IA,IA_Len);
			  if(readDataTmp != 0xffffffff) uiValues.I_value   = readDataTmp;
        readDataTmp = RN_ReadDatas(IB,IB_Len);
			  if(readDataTmp != 0xffffffff) uiValues.IB_value  = readDataTmp;
			  readDataTmp = RN_ReadDatas(IC,IC_Len);
			  if(readDataTmp != 0xffffffff) uiValues.IC_value  = readDataTmp;			
				// 读取电压有效值
			  readDataTmp = RN_ReadDatas(UA,UA_Len);	
			  if(readDataTmp != 0xffffffff) uiValues.U_value   = readDataTmp;
        readDataTmp = RN_ReadDatas(UB,UB_Len);
			  if(readDataTmp != 0xffffffff) uiValues.UB_value  = readDataTmp;
			  readDataTmp = RN_ReadDatas(UC,UC_Len); 
			  if(readDataTmp != 0xffffffff) uiValues.UC_value  = readDataTmp;
			
				// 读取合相有功功率	
        readDataTmp = RN_ReadDatas(PWRT,PWRT_Len);	
			  if(readDataTmp != 0xffffffff) uiValues.PWRT_RMS   = readDataTmp;
        readDataTmp = RN_ReadDatas(PWRA,PWRA_Len);
			  if(readDataTmp != 0xffffffff) uiValues.PWR_RMS   = readDataTmp;
			  readDataTmp = RN_ReadDatas(PWRB,PWRB_Len); 
			  if(readDataTmp != 0xffffffff) uiValues.PWRB_RMS   = readDataTmp;
        readDataTmp = RN_ReadDatas(PWRC,PWRC_Len);	
			  if(readDataTmp != 0xffffffff) uiValues.PWRC_RMS   = readDataTmp;
								
				// 计算电表参数:
				// 电压电流
				UI_Data.I_RMS  = uiValues.I_value * K_IRMS; 
				UI_Data.IB_RMS = uiValues.IB_value * K_IRMS; 
				UI_Data.IC_RMS = uiValues.IC_value * K_IRMS;  
				UI_Data.U_RMS  = uiValues.U_value * K_URMS; 
        UI_Data.UB_RMS = uiValues.UB_value * K_URMS; 
        UI_Data.UC_RMS = uiValues.UC_value * K_URMS;
				// 有功功率
				UI_Data.P_actv  = uiValues.PWR_RMS * K_POWERPA;
				UI_Data.PB_actv = uiValues.PWRB_RMS * K_POWERPB;
				UI_Data.PC_actv = uiValues.PWRC_RMS * K_POWERPC;
				UI_Data.PT_actv = (UI_Data.P_actv < 0 ? UI_Data.P_actv * -1: UI_Data.P_actv) \
				                   + (UI_Data.PB_actv < 0 ? UI_Data.PB_actv * -1: UI_Data.PB_actv) \
													 + (UI_Data.PC_actv < 0 ? UI_Data.PC_actv * -1: UI_Data.PC_actv);
				// 视在功率
				UI_Data.Papt    = UI_Data.I_RMS*UI_Data.U_RMS + UI_Data.IB_RMS*UI_Data.UB_RMS + UI_Data.IC_RMS*UI_Data.UC_RMS;
				
				// 电量值：
				#if (Get_QOE_Method == Meter_GuageIC_RN8302B)
				UI_Data.QOE = uiValues.QOE_value * K_QOE;
				#endif
								
        #ifdef SYS_DEBUG
				// printf(" %.3f  %.3f  \r\n",(uiValues.QOE_value * K_QOE),UI_Data.QOE);
        // printf(" %u %u %u %u %u %u  %u  %u  %u \r\n",uiValues.I_value,uiValues.IB_value,uiValues.IC_value,uiValues.U_value,uiValues.UB_value,uiValues.UC_value,  \
				                               uiValues.PWR_RMS,uiValues.PWRB_RMS,uiValues.PWRC_RMS);
				// printf("  %d  %d  %d  %d  %u  %.2f  %.2f  %.2f  %.2f %.2f \r\n",uiValues.PWR_RMS,uiValues.PWRB_RMS,uiValues.PWRC_RMS,uiValues.PWRT_RMS,uiValues.QOE_value,  \
							UI_Data.P_actv,UI_Data.PB_actv,UI_Data.PC_actv,UI_Data.PT_actv,(UI_Data.I_RMS*UI_Data.U_RMS + UI_Data.IB_RMS*UI_Data.UB_RMS + UI_Data.IC_RMS*UI_Data.UC_RMS));
				
				#endif	
				if(UI_Data.meterReady == 0 && UI_Data.QOE_ChgStart == 0){
					  UI_Data.QOE_ChgStart = UI_Data.QOE;
				}			
				UI_Data.meterReady = 1;				
		}
	  
}
#endif


// 获取电压状态值
void get_U_state(){	
	  // 获取电压状态：
    #if RTC_ON > 0
		getTimestampRTC();
		#endif
    #if meter485_ON > 0
    if(mt485_Data.meterReady == 1){
			  if(IS_U_State_ovrvolt2()){ 
						if(U_CtrData.U_state_pre != U_State_ovrvolt){								
								U_CtrData.Ustt_change_tm = system_time;
						}				
						U_CtrData.U_state_pre = U_State_ovrvolt;				
				}else if(IS_U_State_normal2()){ 
						if(U_CtrData.U_state_pre != U_State_normal){								
								U_CtrData.Ustt_change_tm = system_time;
						}	
						U_CtrData.U_state_pre = U_State_normal;                			  
				}else if(IS_U_State_udrvolt2()){
						if(U_CtrData.U_state_pre != U_State_udrvolt){								
								U_CtrData.Ustt_change_tm = system_time;
						}	
						U_CtrData.U_state_pre = U_State_udrvolt;	
				}else if(IS_U_State_0V2()){
						if(U_CtrData.U_state_pre != U_State_0V){								
								U_CtrData.Ustt_change_tm = system_time;
						}	
						U_CtrData.U_state_pre = U_State_0V;				
				}else{
						if(U_CtrData.U_state_pre != U_State_err){													
								U_CtrData.Ustt_change_tm = system_time; 
						}	
						U_CtrData.U_state_pre = U_State_err;			  
				} 
		}else {
		#endif	  
		    if(IS_U_State_ovrvolt()){ 
						if(U_CtrData.U_state_pre != U_State_ovrvolt){								
								U_CtrData.Ustt_change_tm = system_time;
						}				
						U_CtrData.U_state_pre = U_State_ovrvolt;				
				}else if(IS_U_State_normal()){ 
						if(U_CtrData.U_state_pre != U_State_normal){								
								U_CtrData.Ustt_change_tm = system_time;
						}	
						U_CtrData.U_state_pre = U_State_normal;                			  
				}else if(IS_U_State_udrvolt()){
						if(U_CtrData.U_state_pre != U_State_udrvolt){								
								U_CtrData.Ustt_change_tm = system_time;
						}	
						U_CtrData.U_state_pre = U_State_udrvolt;	
				}else if(IS_U_State_0V()){
						if(U_CtrData.U_state_pre != U_State_0V){								
								U_CtrData.Ustt_change_tm = system_time;
						}	
						U_CtrData.U_state_pre = U_State_0V;				
				}else{
						if(U_CtrData.U_state_pre != U_State_err){													
								U_CtrData.Ustt_change_tm = system_time; 
						}	
						U_CtrData.U_state_pre = U_State_err;			  
				}   			
		#if meter485_ON > 0	
		}
    #endif
    
		// 获取上电时间
		if(U_CtrData.U_state_pre == U_State_0V){
			  if(U_CtrData.POWER_ON_Tm > 0) U_CtrData.POWER_ON_Tm = 0;
		} else {
			  if(U_CtrData.POWER_ON_Tm == 0) U_CtrData.POWER_ON_Tm = system_time;
		}
		
		// 获取真正的状态值；		
		if(system_time - U_CtrData.Ustt_change_tm > U_Change_Tm_avail && U_CtrData.Ustt_change_tm != 0){
        if(U_CtrData.U_state != U_CtrData.U_state_pre){					   
					  U_CtrData.Ustt_change_stabi_tm = system_time; 
				}        			
				U_CtrData.U_state  = U_CtrData.U_state_pre;
        #if Volt_Protection > 0			
			  // 不同的电压状态进行不同处理			  
			  if(U_CtrData.U_state == U_State_ovrvolt && system_time - U_CtrData.Ustt_change_stabi_tm > U_Wait_TmEnd){ 
					  // 过压异常
					  mTask_Fault = mTask_Fault | (0x0001 << (over_voltage - 1));	
			  }else if(U_CtrData.U_state == U_State_udrvolt && system_time - U_CtrData.Ustt_change_stabi_tm > U_Wait_TmEnd){ 
					  // 欠压异常：PCB通电后，启动半分钟内不处理					  				  
						mTask_Fault = mTask_Fault | (0x0001 << (low_voltage - 1));											  
				}else if(U_CtrData.U_state == U_State_normal && system_time - U_CtrData.Ustt_change_stabi_tm > U_Recv_TmEnd){ 
					  // 正常10秒，才能恢复充电：
						if(faultCode == low_voltage || faultCode == over_voltage){ 
							  // 电压恢复正常
					      mTask_Fault = mTask_Fault & (~(0x0001 << (faultCode - 1))); //位置0
							  main_update = 1;  //刷新一下显示灯;
						}						
				}else if(U_CtrData.U_state == U_State_err){
        #else
				if(U_CtrData.U_state == U_State_err){
        #endif					
					  // 电压测量坏了,立马断电 
					  if(system_time - led_startUp_TmRecode > 30000){
					      mTask_Fault = mTask_Fault | (0x0001 << (U_data_e - 1));
            }							
				}				
		}
}

// 获取额定电流
void get_I_rated_value(){
	  #if flexible_rated_value > 0
	    get_rated_value();
	  #endif
	  ///////////////////// 外接电表 //////////////////////
    #if meter485_ON > 0
			// 调整阈值	
			I_State_Flag.I_adjust2 = I_State_Flag.I_rated_value2 + I_thrhld_Adj2; 
			// 过流阈值
			I_State_Flag.I_over_current2 = I_State_Flag.I_rated_value2 + (I_State_Flag.I_rated_value2 * I_tldRatio_over2 > I_thrhld_over2 ? I_State_Flag.I_rated_value2 * I_tldRatio_over2 : I_thrhld_over2);
			I_State_Flag.I_over_current2 = I_State_Flag.I_over_current2 > I_thrhld_over_max2 ? I_thrhld_over_max2 : I_State_Flag.I_over_current2;		
			// 短路阈值
			I_State_Flag.I_short_circuit2 = I_State_Flag.I_rated_value2 + (I_State_Flag.I_rated_value2 * I_tldRatio_short2 > I_thrhld_short2 ? I_State_Flag.I_rated_value2 * I_tldRatio_short2 : I_thrhld_short2);
			I_State_Flag.I_short_circuit2 = I_State_Flag.I_short_circuit2 > I_thrhld_short_max2 ? I_thrhld_short_max2 : I_State_Flag.I_short_circuit2;   
			// 浮充
			I_State_Flag.I_float_chg2 = I_thrhld_fltChg2;
		#endif
	  ////////////////////  主板计量芯片 ///////////////////
	  #if (UI_Meter_Method == Meter_SelfADC) && (GET_UI_METHOD_ID == UI_METHOD_RMS)
	  uint32_t addTmp = 0;
	  uint32_t addTmp2 = 0;
	  #endif
		// 调整阈值		    
		#if (UI_Meter_Method == Meter_SelfADC) && (GET_UI_METHOD_ID == UI_METHOD_RMS) 
		I_State_Flag.I_adjust = I_State_Flag.I_rated_value + I_thrhld_Adj + sqrt(I_State_Flag.I_rated_value)*sqrt(I_thrhld_Adj)*2; 
		#else
		I_State_Flag.I_adjust = I_State_Flag.I_rated_value + I_thrhld_Adj; 
		#endif	
		// 过流阈值
		#if (UI_Meter_Method == Meter_SelfADC) && (GET_UI_METHOD_ID == UI_METHOD_RMS)
		addTmp = (I_State_Flag.I_rated_value * I_tldRatio_over > I_thrhld_over ? I_State_Flag.I_rated_value * I_tldRatio_over : I_thrhld_over);
		I_State_Flag.I_over_current = I_State_Flag.I_rated_value + addTmp + sqrt(I_State_Flag.I_rated_value)*sqrt(addTmp)*2;
		#else
		I_State_Flag.I_over_current = I_State_Flag.I_rated_value + (I_State_Flag.I_rated_value * I_tldRatio_over > I_thrhld_over ? I_State_Flag.I_rated_value * I_tldRatio_over : I_thrhld_over);		
		#endif		
		I_State_Flag.I_over_current = I_State_Flag.I_over_current > I_thrhld_over_max ? I_thrhld_over_max : I_State_Flag.I_over_current;		
		// 短路阈值
		#if (UI_Meter_Method == Meter_SelfADC) && (GET_UI_METHOD_ID == UI_METHOD_RMS)
		addTmp2 = (I_State_Flag.I_rated_value * I_tldRatio_short > I_thrhld_short ? I_State_Flag.I_rated_value * I_tldRatio_short : I_thrhld_short);
		I_State_Flag.I_short_circuit = I_State_Flag.I_rated_value + addTmp2 + sqrt(I_State_Flag.I_rated_value)*sqrt(addTmp2)*2;	
		#else
		I_State_Flag.I_short_circuit = I_State_Flag.I_rated_value + (I_State_Flag.I_rated_value * I_tldRatio_short > I_thrhld_short ? I_State_Flag.I_rated_value * I_tldRatio_short : I_thrhld_short);		
		#endif
		I_State_Flag.I_short_circuit = I_State_Flag.I_short_circuit > I_thrhld_short_max ? I_thrhld_short_max : I_State_Flag.I_short_circuit;				
		// 浮充阈值
		I_State_Flag.I_float_chg = I_thrhld_fltChg;		
}

// 获取电流状态
void get_I_state(){    
	  #ifdef SYS_DEBUG
	  //printf("I_state = %d  %d,  I = %.2f %u, rated = %u,  adj = %u,  ovr = %u,  sht = %u,  float = %u, ist = %.2f  t = %llu  %llu  %llu \n\r", \
	          I_CtrData.I_state,I_CtrData.I_state_pre,UI_Data.I_RMS,uiValues.I_value,I_State_Flag.I_rated_value,I_State_Flag.I_adjust, \
	          I_State_Flag.I_over_current,I_State_Flag.I_short_circuit,I_State_Flag.I_float_chg,ISrt_value, \
	          (system_time - I_CtrData.Istt_change_tm),(system_time - I_CtrData.Istt_change_stabi_tm),(system_time - I_CtrData.Istt_change_normal_tm));
		#endif
	  // 获取电流状态数据
	  #if RTC_ON > 0
		getTimestampRTC();
		#endif
	  #if meter485_ON > 0
	  if(mt485_Data.meterReady == 1){
			  //printf(" %u  %u  %u  %u  %u \r\n",I_State_Flag.I_short_circuit2,I_State_Flag.I_over_current2,I_State_Flag.I_adjust2,I_State_Flag.I_rated_value2,uiValues2.I_value);
			  if(IS_I_state_short_circuit2()){ 
						if(I_CtrData.I_state_pre != I_state_short_circuit){ 					  
								I_CtrData.Istt_change_tm = system_time; 
						}
						I_CtrData.I_state_pre = I_state_short_circuit;
				}else if(IS_I_state_over_current2()){ 
						if(I_CtrData.I_state_pre != I_state_over_current){            		
								I_CtrData.Istt_change_tm = system_time;  
						}
						I_CtrData.I_state_pre = I_state_over_current;
				}else if(IS_I_state_adjust2()){
						if(I_CtrData.I_state_pre != I_state_adjust){ 
								I_CtrData.Istt_change_tm = system_time;  
						}
						I_CtrData.I_state_pre = I_state_adjust;
				}else if(IS_I_state_normal2()){ 
						if(I_CtrData.I_state_pre != I_state_normal){
								I_CtrData.Istt_change_tm = system_time; 
						}
						I_CtrData.I_state_pre = I_state_normal; 
				} else if(IS_I_state_float_chg2()){  
						if(I_CtrData.I_state_pre != I_state_float_chg){ 
								I_CtrData.Istt_change_tm = system_time;
						}
						I_CtrData.I_state_pre = I_state_float_chg;         
				} else if(IS_I_state_stop_chg2()){  
						if(I_CtrData.I_state_pre != I_state_stop_chg){ 
								I_CtrData.Istt_change_tm = system_time; 
						}
						I_CtrData.I_state_pre = I_state_stop_chg;
				} else {
						if(I_CtrData.I_state_pre != I_state_err){ 
								I_CtrData.Istt_change_tm = system_time;
						}
						I_CtrData.I_state_pre = I_state_err;
				}		
		}else {
		#endif	  
		    if(IS_I_state_short_circuit()){ 
						if(I_CtrData.I_state_pre != I_state_short_circuit){ 					  
								I_CtrData.Istt_change_tm = system_time; 
						}
						I_CtrData.I_state_pre = I_state_short_circuit;
				}else if(IS_I_state_over_current()){ 
						if(I_CtrData.I_state_pre != I_state_over_current){            		
								I_CtrData.Istt_change_tm = system_time;  
						}
						I_CtrData.I_state_pre = I_state_over_current;
				}else if(IS_I_state_adjust()){
						if(I_CtrData.I_state_pre != I_state_adjust){ 
								I_CtrData.Istt_change_tm = system_time;  
						}
						I_CtrData.I_state_pre = I_state_adjust;
				}else if(IS_I_state_normal()){ 
						if(I_CtrData.I_state_pre != I_state_normal){
								I_CtrData.Istt_change_tm = system_time; 
						}
						I_CtrData.I_state_pre = I_state_normal; 
				} else if(IS_I_state_float_chg()){  
						if(I_CtrData.I_state_pre != I_state_float_chg){ 
								I_CtrData.Istt_change_tm = system_time;
						}
						I_CtrData.I_state_pre = I_state_float_chg;         
				} else if(IS_I_state_stop_chg()){  
						if(I_CtrData.I_state_pre != I_state_stop_chg){ 
								I_CtrData.Istt_change_tm = system_time; 
						}
						I_CtrData.I_state_pre = I_state_stop_chg;
				} else {
						if(I_CtrData.I_state_pre != I_state_err){ 
								I_CtrData.Istt_change_tm = system_time; 
						}
						I_CtrData.I_state_pre = I_state_err;
				}		
		#if meter485_ON > 0	
		}
    #endif
		
		// 持续性计时靠2个变量控制，Istt_change_tm 和 fault_start_tm；
		// 检测电流状态：[检测状态和恢复不能同时执行，否则错误处理会漏掉; 所以Istt_change_tm 必须刷新下]
    if(system_time - I_CtrData.Istt_change_tm > IState_availTm && I_CtrData.Istt_change_tm > 0){
			  // 状态生效：
			  if(I_CtrData.I_state != I_CtrData.I_state_pre){
					  I_CtrData.Istt_change_stabi_tm = system_time;
            if(!((I_CtrData.I_state == I_state_normal || I_CtrData.I_state == I_state_stop_chg || I_CtrData.I_state == I_state_float_chg) \
							 && (I_CtrData.I_state_pre == I_state_normal || I_CtrData.I_state_pre == I_state_stop_chg || I_CtrData.I_state_pre == I_state_float_chg))){
							  I_CtrData.Istt_change_normal_tm = system_time;
						}					
				}
			  I_CtrData.I_state  = I_CtrData.I_state_pre;
           			
			  // 各种状态的处理：
			  #ifdef SYS_DEBUG
			  // printf("get_I_state = %d,  tms = %d  \n\r",I_state,faultOcc_IOvrRecv_counts);
		    #endif
			  if(I_CtrData.I_state ==  I_state_over_current && system_time - I_CtrData.Istt_change_stabi_tm > IState_over_prt){
					  // 过流处理；等待恢复期，和 恢复期结束了才能继续过流检测处理
					  mTask_Fault = mTask_Fault | (0x0001 << (over_current - 1));
					  //printf(" ==== %u   %.2f  ==== \r\n",mTask_Fault,UI_Data.I_RMS);
				}else if(I_CtrData.I_state == I_state_adjust && system_time - I_CtrData.Istt_change_stabi_tm > IAdj_intv){
					  // 调整处理
					  mTask_Fault = mTask_Fault | (0x0001 << (Istate_adjust - 1));			
				}else if(I_CtrData.I_state == I_state_short_circuit && system_time - I_CtrData.Istt_change_stabi_tm > IState_short_prst){
					  // 短路处理
					  ISrt_value = UI_Data.I_RMS; // 记录短路电流;				    
				    mTask_Fault = mTask_Fault | (0x0001 << (short_circuit - 1));					  
				}else if(I_CtrData.I_state == I_state_normal || I_CtrData.I_state == I_state_stop_chg || I_CtrData.I_state == I_state_float_chg){
            // 恢复充电：
						if(faultCode == over_current && system_time - I_CtrData.Istt_change_normal_tm > IState_over_recv){
							  if(faultOcc_IOvrRecv_counts < IOvState_recv_tms){
									  // 电流恢复正常处理
										mTask_Fault = mTask_Fault & (~(0x0001 << (faultCode - 1))); //位置0 
										main_update = 1;  //刷新一下显示灯;
									  faultOcc_IOvrRecv_counts++;
								}
						}	else if(faultCode == Istate_adjust){
							  // 电流恢复正常处理
					      mTask_Fault = mTask_Fault & (~(0x0001 << (faultCode - 1))); //位置0 
                main_update = 1;  //刷新一下显示灯;							
						}		  
            // 特殊处理：
            if(I_CtrData.I_state == I_state_stop_chg){
								// 电流 = 0; 充电停止。
								
						}else if(I_CtrData.I_state == I_state_float_chg){
								// 浮充检测到：
							  #if RTC_ON > 0
								getTimestampRTC();
								#endif							  
								if(system_time - I_CtrData.Istt_change_stabi_tm  > thrhld_fltChg_tm && Rly_status == 1){
										// 充电处于浮充阶段
										chg_stage = CHG_FULL;
									  main_update = 1;  //刷新一下显示灯;	
								}		
						}	else if(I_CtrData.I_state < I_state_float_chg){
							  #if RTC_ON > 0
								getTimestampRTC();
								#endif
							  if(chg_start_tm > 0 && system_time - chg_start_tm > Chging_Avail_tm){
									  // 正在充电
										if(chg_stage != CHG_STOP)
										{
											chg_stage = CHG_CHARGING;
										}
								}
						}
				}else if(I_CtrData.I_state == I_state_err){
					  // 电流计量坏了; 立马停充
					  mTask_Fault = mTask_Fault | (0x0001 << (I_data_e - 1));	
				}	
		}
}

// 获取CP值的范围id值：
void get_cp_value_id(){
#if AUTHEN_CE > 0
	  if(cp_data.cp_up_or_down == cp_Direc_Down){
			  // 下降方向：开启充电
			  if(cp_data.ADC_Data >= cp_Dn12V_low){
						cp_data.value_cope_id = CP_12;
				}else if(cp_data.ADC_Data >= cp_Dn9V_low && cp_data.ADC_Data < cp_Dn9V_high){
						cp_data.value_cope_id = CP_9;
				}else if(cp_data.ADC_Data >= cp_Dn6V_low && cp_data.ADC_Data < cp_Dn6V_high){
						cp_data.value_cope_id = CP_6;
				}else if(cp_data.ADC_Data < cp_Dn0V_high){
						cp_data.value_cope_id = CP_0;			
				}			  
    }else if(cp_data.cp_up_or_down == cp_Direc_UP){
			  // 上升方向
			  if(cp_data.ADC_Data >= cp_UP12V_low){
						cp_data.value_cope_id = CP_12;
				}else if(cp_data.ADC_Data >= cp_UP9V_low && cp_data.ADC_Data < cp_UP9V_high){
						cp_data.value_cope_id = CP_9;
				}else if(cp_data.ADC_Data >= cp_UP6V_low && cp_data.ADC_Data < cp_UP6V_high){
						cp_data.value_cope_id = CP_6;
				}else if(cp_data.ADC_Data < cp_UP0V_high){
						cp_data.value_cope_id = CP_0;
				}			  
		} else {
			  if(cp_data.ADC_Data >= cp_Dn12V_low){
						cp_data.value_cope_id = CP_12;
				}else if(cp_data.ADC_Data >= cp_Dn9V_low && cp_data.ADC_Data < cp_Dn9V_high){
						cp_data.value_cope_id = CP_9;
				}else if(cp_data.ADC_Data >= cp_Dn6V_low && cp_data.ADC_Data < cp_Dn6V_high){
						cp_data.value_cope_id = CP_6;
				}else if(cp_data.ADC_Data < cp_Dn0V_high){
						cp_data.value_cope_id = CP_0;			
				}		
		}
#else
	  if(cp_data.ADC_Data >= cp_12V_low){
			  cp_data.value_cope_id = CP_12;
		}else if(cp_data.ADC_Data >= cp_9V_low && cp_data.ADC_Data < cp_9V_high){
			  cp_data.value_cope_id = CP_9;
		}else if(cp_data.ADC_Data >= cp_6V_low && cp_data.ADC_Data < cp_6V_high){
			  cp_data.value_cope_id = CP_6;
		}else if(cp_data.ADC_Data < cp_0V_high){
			  cp_data.value_cope_id = CP_0;			
		}
#endif	
//		if(cp_data.value_cope_id == CP_0){
//			  if(cp_data.CP_Start_Tm > 0) cp_data.CP_Start_Tm = 0;
//		}else{
//			  #if RTC_ON > 0
//				getTimestampRTC();
//				#endif
//			  if(cp_data.CP_Start_Tm == 0) cp_data.CP_Start_Tm = system_time;
//		}
}

// 获取CP状态：
void get_cp_state(){
	  // 分析CP数据：	
	  get_cp_value_id();
	  #ifdef SYS_DEBUG
	  // printf("get_cp_state = %d, %f, %d, %d, %d;  %lld  \n\r",cp_data.ADC_Data,cp_data.CP_Value, cp_data.value_cope_id,cp_data.cp_state,cp_data.cp_state_pre,cp_data.CP_idChg_Tm);
	  #endif
#if AUTHEN_CE > 0
	  if(cp_data.value_cope_id == CP_12){
			  cp_data.cp_up_or_down = cp_Direc_Down;
		} else if(cp_data.value_cope_id == CP_6 || cp_data.value_cope_id == CP_0){
			  cp_data.cp_up_or_down = cp_Direc_UP;
		} else if(cp_data.value_cope_id == CP_9){
			  if(cp_data.value_cope_id < cp_data.value_cope_id_pre){
						cp_data.cp_up_or_down = cp_Direc_Down;
				}else if(cp_data.value_cope_id > cp_data.value_cope_id_pre){
						cp_data.cp_up_or_down = cp_Direc_UP;
				} 
		} else {
			  cp_data.cp_up_or_down = cp_Direc_Down;
		}	  
#endif
    if(cp_data.value_cope_id == CP_12){        				
        if(cp_data.cp_state_pre != NO_PLUGGED){
					  #if RTC_ON > 0
						getTimestampRTC();
						#endif
						cp_data.CP_idChg_Tm = system_time;
				}	
				if(cp_data.cp_state_pre != PLUGGED && cp_data.cp_state_pre != NO_PLUGGED){
					  #if RTC_ON > 0
						getTimestampRTC();
						#endif
				    cp_data.CP_9_12_Chg_Tm = system_time;
				}		
				cp_data.cp_state_pre = NO_PLUGGED;
				if(cp_data.value_cope_id_pre != CP_12 && cp_data.value_cope_id_pre != CP_0){					  
					  cp_data.cp_state_sub = PLUG_OUT;
            chg_stage = CHG_PLUG_OUT;					
				}
				if(cp_data.cp_state_sub == 0){
					  chg_stage = CHG_IDLE;	
				}
		}else if(cp_data.value_cope_id == CP_9){			  
			  if(cp_data.cp_state_pre != PLUGGED && cp_data.cp_state_pre != NO_PLUGGED){
					  #if RTC_ON > 0
						getTimestampRTC();
						#endif
				    cp_data.CP_9_12_Chg_Tm = system_time;
				}			
			  if(cp_data.cp_state_pre != PLUGGED){
					  #if RTC_ON > 0
						getTimestampRTC();
						#endif
					  cp_data.CP_idChg_Tm = system_time;					  		  
				} 
				cp_data.cp_state_pre = PLUGGED;
				if(cp_data.value_cope_id_pre == CP_12){
					  cp_data.cp_state_sub = PLUG_IN;
					  chg_stage = CHG_PLUG_IN;	
				}else if(cp_data.value_cope_id_pre == CP_6){
					  cp_data.cp_state_sub = CHG_Fini;	
            main_update = 1; //刷新灯					
				}
		}else if(cp_data.value_cope_id == CP_6){			  
			  if(cp_data.cp_state_pre != BE_CHARGING){
					  #if RTC_ON > 0
						getTimestampRTC();
						#endif
            cp_data.CP_idChg_Tm = system_time;
            cp_data.CP_9_12_Chg_Tm = system_time;					
				}
				cp_data.cp_state_pre = BE_CHARGING;
				if(cp_data.value_cope_id_pre != CP_6){
					  cp_data.cp_state_sub = CHG_Strt;
				}
		}else if(cp_data.value_cope_id == CP_0){
			  if(cp_data.cp_state_pre != CP_ERROR){
					  #if RTC_ON > 0
						getTimestampRTC();
						#endif
					  cp_data.CP_idChg_Tm = system_time;
					  cp_data.CP_9_12_Chg_Tm = system_time;
				}
			  cp_data.cp_state_pre = CP_ERROR;
		}
		
		// 记录id编号：
		cp_data.value_cope_id_pre = cp_data.value_cope_id;
		
		// 只有坚持20ms的状态，才能正式取用;	
		#if RTC_ON > 0
		getTimestampRTC();
		#endif
		CP_idChg = system_time - cp_data.CP_idChg_Tm > CP_Change_Tm_avail;
		CP_9_12_Chg = system_time - cp_data.CP_9_12_Chg_Tm > CP_Change_Tm_avail; // 非6V时间
    if(CP_idChg || CP_9_12_Chg){
			  if(cp_data.cp_state != BE_CHARGING && cp_data.cp_state_pre == BE_CHARGING) cp_data.CP_Jump_tms++;
			  if(CP_9_12_Chg && (!CP_idChg)) cp_data.cp_state = PLUGGED; 
				else cp_data.cp_state  = cp_data.cp_state_pre;
		}
		
		// CP后处理
		if(!cp_data.CP_State_Post_delay--) get_cp_state_post();
}

// CP状态后处理: 50*5 = 250ms一次;
void get_cp_state_post(){
    // CP细节状态恢复至主状态，类似弹窗的效果。
		if(cp_data.CP_idChg_Tm > 0 && cp_data.cp_state_sub > 0){
			  #if RTC_ON > 0
				getTimestampRTC();
				#endif
			  if(system_time - cp_data.CP_idChg_Tm > CPState_ChgFini_Stable_Tm){
						cp_data.cp_state_sub = 0;	
            main_update = 1; //刷新灯					
				} else {
					  #if RTC_ON > 0
						getTimestampRTC();
						#endif
						if(cp_data.cp_state_sub != CHG_Fini && system_time - cp_data.CP_idChg_Tm > CPState_Stable_Tm){
								cp_data.cp_state_sub = 0;
							  main_update = 1; //刷新灯
						}			
				}
		}
    // CP错误处理，以及插枪和拔枪的识别
    if(cp_data.cp_state == CP_ERROR){
				#if RTC_ON > 0
				getTimestampRTC();
				#endif
				if(system_time - cp_data.CP_idChg_Tm > CP_err_Tm_avail && U_CtrData.U_state > 0 && U_CtrData.U_state < U_State_err){
						//此时才算是错误：					  
						faultCode = cp_fault;
						mTask_Fault = mTask_Fault | (0x0001 << (cp_fault - 1));     //位置1	
						// printf(" CP ERROR 111111 \n\r");						
						// printf(" CP ERROR = %f, %d, %d, %d  %lld; \n\r",cp_data.CP_Value, cp_data.value_cope_id,cp_data.cp_state,cp_data.cp_state_pre,cp_data.CP_idChg_Tm);
				}					  
		} else {
			  // CP值异常的恢复：CP跳变不恢复		
				if(cp_data.CP_Jump_tms <= CP_Jump_max_tms){
						// CP 恢复正常
						mTask_Fault = mTask_Fault & (~(0x0001 << (cp_fault - 1)));   //位置0
				}
				#if CC_Detect_type == 0
				// 拔枪操作
				if(cp_data.cp_state ==  NO_PLUGGED){
						if(plug_out_times == 100){
								// 检测到拔枪动作：并执行拔枪后的任务;		
								plug_out_times++;							
								plug_out_action();
						}							  
				}else{
						plug_out_times = 100;
				}
				
				// 插枪操作：
				if(cp_data.cp_state ==  PLUGGED || cp_data.cp_state ==  BE_CHARGING){ 
						if(plug_in_times == 55){
								plug_in_times++;
								plug_in_action();
						}                
				}else{
						if(cp_data.cp_state ==  NO_PLUGGED){
								plug_in_times = 55;
						}
				}
				#endif
		}		
		// 检测CP跳变错误
		if(cp_data.CP_Jump_tms > CP_Jump_max_tms){			  
			  faultCode = cp_fault;
				// 发出CP错误：
			  mTask_Fault = mTask_Fault | (0x0001 << (cp_fault - 1));  //位置	
		}
		
		cp_data.CP_State_Post_delay = CP_State_Post_delay_default;
		#ifdef SYS_DEBUG
		//printf(" CP_Jump_tms = %d %lld %d  %d  \n",CP_Jump_tms,CP_startChg_Tm, mTask_Fault ,faultCode);		
		#endif
}

// 获取温度状态：
#if tmpr_EN > 0
void get_tmpr_state(){
	  uint16_t tmrp = TMP_BoardIn_R;    
	  // 选取温度计
	  #if tmpr_nums > 1
	  // 选用不同的传感器
	  if(tmpr_CtrData.tmrp_using_id == tmrp_using_boardIn){
			  tmrp = TMP_BoardIn_R;
			  if(tmrp < tmpr_limit_low_R && tmrp >= tmpr_normal_R){
						if(tmpr_CtrData.tmpr_state_pre != tmprState_BoardIn_normal){
							  #if RTC_ON > 0
								getTimestampRTC();
								#endif
								tmpr_CtrData.tmpr_change_tm = system_time;
						}				
						tmpr_CtrData.tmpr_state_pre = tmprState_BoardIn_normal;	
				}else if(tmrp < tmpr_normal_R && tmrp >= tmpr_adjust_R){
						if(tmpr_CtrData.tmpr_state_pre != tmprState_BoardIn_warn){
							  #if RTC_ON > 0
								getTimestampRTC();
								#endif
								tmpr_CtrData.tmpr_change_tm = system_time;
						}				
						tmpr_CtrData.tmpr_state_pre = tmprState_BoardIn_warn;	
				}else if(tmrp < tmpr_adjust_R && tmrp >= tmpr_stop_R){
						if(tmpr_CtrData.tmpr_state_pre != tmprState_BoardIn_adjust){
							  #if RTC_ON > 0
								getTimestampRTC();
								#endif
								tmpr_CtrData.tmpr_change_tm = system_time;
						}	
						tmpr_CtrData.tmpr_state_pre = tmprState_BoardIn_adjust;                			  
				}else if(tmrp < tmpr_stop_R && tmrp > tmpr_limit_high_R){
						if(tmpr_CtrData.tmpr_state_pre != tmprState_BoardIn_stop){
							  #if RTC_ON > 0
								getTimestampRTC();
								#endif
								tmpr_CtrData.tmpr_change_tm = system_time;
						}	
						tmpr_CtrData.tmpr_state_pre = tmprState_BoardIn_stop;
				} else {
						// 温度计坏了：数字过大
						if(tmpr_CtrData.tmpr_state_pre != tmprState_BoardIn_err){
							  #if RTC_ON > 0
								getTimestampRTC();
								#endif
								tmpr_CtrData.tmpr_change_tm = system_time;
						}	
						tmpr_CtrData.tmpr_state_pre = tmprState_BoardIn_err;
				}	
			  tmpr_CtrData.tmrp_using_id = tmrp_using_Ext1;  // 轮流鉴定状态
		}else if(tmpr_CtrData.tmrp_using_id == tmrp_using_Ext1){
		    tmrp = TMP_Ext1_R;
			  if(tmrp < tmprExt_limit_low_R && tmrp >= tmprExt_normal_R){
						if(tmpr_CtrData.tmpr_state_pre != tmprState_BoardIn_normal){
							  #if RTC_ON > 0
								getTimestampRTC();
								#endif
								tmpr_CtrData.tmpr_change_tm = system_time;
						}				
						tmpr_CtrData.tmpr_state_pre = tmprState_BoardIn_normal;	
				}else if(tmrp < tmprExt_normal_R && tmrp >= tmprExt_adjust_R){
						if(tmpr_CtrData.tmpr_state_pre != tmprState_BoardIn_warn){
							  #if RTC_ON > 0
								getTimestampRTC();
								#endif
								tmpr_CtrData.tmpr_change_tm = system_time;
						}				
						tmpr_CtrData.tmpr_state_pre = tmprState_BoardIn_warn;	
				}else if(tmrp < tmprExt_adjust_R && tmrp >= tmprExt_stop_R){
						if(tmpr_CtrData.tmpr_state_pre != tmprState_BoardIn_adjust){
							  #if RTC_ON > 0
								getTimestampRTC();
								#endif
								tmpr_CtrData.tmpr_change_tm = system_time;
						}	
						tmpr_CtrData.tmpr_state_pre = tmprState_BoardIn_adjust;                			  
				}else if(tmrp < tmprExt_stop_R && tmrp > tmprExt_limit_high_R){
						if(tmpr_CtrData.tmpr_state_pre != tmprState_BoardIn_stop){
							  #if RTC_ON > 0
								getTimestampRTC();
								#endif
								tmpr_CtrData.tmpr_change_tm = system_time;
						}	
						tmpr_CtrData.tmpr_state_pre = tmprState_BoardIn_stop;
				} else {
						// 温度计坏了：数字过大
						if(tmpr_CtrData.tmpr_state_pre != tmprState_BoardIn_err){
							  #if RTC_ON > 0
								getTimestampRTC();
								#endif
								tmpr_CtrData.tmpr_change_tm = system_time;
						}	
						tmpr_CtrData.tmpr_state_pre = tmprState_BoardIn_err;
				}	
			  tmpr_CtrData.tmrp_using_id = tmrp_using_boardIn;
		}	  
	  #else
    if(tmrp < tmpr_limit_low_R && tmrp >= tmpr_normal_R){
			  if(tmpr_CtrData.tmpr_state_pre != tmprState_BoardIn_normal){
		        #if RTC_ON > 0
						getTimestampRTC();
						#endif
				    tmpr_CtrData.tmpr_change_tm = system_time;
				}				
			  tmpr_CtrData.tmpr_state_pre = tmprState_BoardIn_normal;	
		}else if(tmrp < tmpr_normal_R && tmrp >= tmpr_adjust_R){
			  if(tmpr_CtrData.tmpr_state_pre != tmprState_BoardIn_warn){
		        #if RTC_ON > 0
						getTimestampRTC();
						#endif
				    tmpr_CtrData.tmpr_change_tm = system_time;
				}				
			  tmpr_CtrData.tmpr_state_pre = tmprState_BoardIn_warn;	
		}else if(tmrp < tmpr_adjust_R && tmrp >= tmpr_stop_R){
			  if(tmpr_CtrData.tmpr_state_pre != tmprState_BoardIn_adjust){
		        #if RTC_ON > 0
						getTimestampRTC();
						#endif
				    tmpr_CtrData.tmpr_change_tm = system_time;
				}	
			  tmpr_CtrData.tmpr_state_pre = tmprState_BoardIn_adjust;                			  
		}else if(tmrp < tmpr_stop_R && tmrp > tmpr_limit_high_R){
			  if(tmpr_CtrData.tmpr_state_pre != tmprState_BoardIn_stop){
				    #if RTC_ON > 0
						getTimestampRTC();
						#endif
				    tmpr_CtrData.tmpr_change_tm = system_time;
				}	
			  tmpr_CtrData.tmpr_state_pre = tmprState_BoardIn_stop;
		} else {
			  // 温度计坏了：数字过大
			  if(tmpr_CtrData.tmpr_state_pre != tmprState_BoardIn_err){
				    #if RTC_ON > 0 
						getTimestampRTC(); 
						#endif
				    tmpr_CtrData.tmpr_change_tm = system_time; 
				}	
			  tmpr_CtrData.tmpr_state_pre = tmprState_BoardIn_err; 
		}	
		#endif	
					  
		// 温度状态稳定性验证，并处理	
    #if RTC_ON > 0
		getTimestampRTC();
		#endif		
		if(system_time - tmpr_CtrData.tmpr_change_tm > tmprState_availTm && tmpr_CtrData.tmpr_change_tm != 0){			  
			  // 温度值生效
			  tmpr_CtrData.tmpr_state  = tmpr_CtrData.tmpr_state_pre;			  
			  // 不同温度状态不同处理
			  #if RTC_ON > 0
				getTimestampRTC();
				#endif
			  if(tmpr_CtrData.tmpr_state == tmprState_BoardIn_normal){
            // 恢复正常的充电模式：正常归位状态坚持时间tmpr_WaitTm=60秒;
					  #if RTC_ON > 0
						getTimestampRTC();
						#endif
						if(faultCode == over_tempr && (system_time - tmpr_CtrData.tmpr_change_tm > tmpr_WaitTm)){
							  // 正常温度：将温度错误归位;
					      mTask_Fault = mTask_Fault & (~(0x0001 << (faultCode - 1))); //位置0 
							  main_update = 1;  //刷新一下显示灯;
							  #ifdef SYS_DEBUG
								printf(" recover charge 01 faultCode = %d \n\r",faultCode);
								#endif
						}	else if(faultCode == tmpr_adjust_err && (system_time - tmpr_CtrData.tmpr_change_tm > tmpr_WaitTm)){
							  // 正常温度：将温度错误归位;
					      mTask_Fault = mTask_Fault & (~(0x0001 << (faultCode - 1))); //位置0 
							  main_update = 1;  //刷新一下显示灯;
							  #ifdef SYS_DEBUG
								printf(" recover charge 02 faultCode = %d \n\r",faultCode);
								#endif
						}
				}else if(tmpr_CtrData.tmpr_state == tmprState_BoardIn_adjust && system_time - tmpr_CtrData.tmpr_change_tm > tmpr_WaitTm){
					  // 温度调整:不显示温度过高错误；但是在过温故障中，处理。
					  // printf("get_tmpr_state = %d, pre = %d  ajtm = %lld  \r\n",tmpr_state, tmpr_state_pre,tmprAdj_start_tm);	
					  mTask_Fault = mTask_Fault | (0x0001 << (tmpr_adjust_err - 1));
				}else if(tmpr_CtrData.tmpr_state == tmprState_BoardIn_stop && system_time - tmpr_CtrData.tmpr_change_tm > tmpr_WaitTm){
					  mTask_Fault = mTask_Fault | (0x0001 << (over_tempr - 1));  //位置1		
        } else if(tmpr_CtrData.tmpr_state == tmprState_BoardIn_warn){
					  // 温度警告期不做任何动作	
				} else if(tmpr_CtrData.tmpr_state == tmprState_BoardIn_err){
					  // 温度计坏了：进行异常处理：并停充不恢复
					  mTask_Fault = mTask_Fault | (0x0001 << (tmpr_boardIn_e - 1));  //位置1
				}
		}
}
#endif

// 漏电处理:只有1的时候执行;
void leakage_event_treat(){
	  // 检测漏电持续时间和动作	
	  #if RCD_TYPE_B > 0
		if(leakData.leak_test_init_step >= Leak_Step_max){
		#endif
			  if(cp_data.value_cope_id == CP_12 || cp_data.value_cope_id == CP_0)  return;	
			
			  #if RCD_Detect == RCD_Detect_POLL
			  if(leakData.leak_tms > leakage_Avail_tms){
				#endif	
					  // 保存CP电压值：//测试版本，apptest，测完去掉
					  //writeData[CP_leak_value_idx].intData = cp_data.ADC_Data;
					  //flash_write();
					
					  faultCode = leakage;
						// 漏电异常，发出处理			  
						mTask_Fault = mTask_Fault | (0x0001 << (leakage - 1));  //位置1
						// 直接停充：快速响应
						chgForbid = leakage; // 必须此处加禁止重启代码，否则mTask_Fault有时差，容易重启。
						PWM_Duty_Set(DUTY_CYCLE_stop);
						Rly_off();
				#if RCD_Detect == RCD_Detect_POLL
				}	
        #endif				
		#if RCD_TYPE_B > 0
		} 
    #if leak_testSelf_get > 0	
    else {
			  if(leakData.leak_testSelf_occs < 252) leakData.leak_testSelf_occs++;
		}		
		#endif
	  #endif   	 
}


// 获取接地状态：
#ifndef UsingFreeRTOS
#if PE_ON > 0
void get_PE_state(){
	  // 获取状态：	
    #if RTC_ON > 0
		getTimestampRTC();
		#endif
		if(system_time - PE_occ_recode > PE_Available_tm && PE_occ_recode > 0){
				// 5s都没有改变; 就没有接地;
			  PE_state = 0;	
        #if RTC_ON > 0
				getTimestampRTC();
				#endif
			  if(system_time - PE_occ_recode > PE_wait_tmEnd){
					  // 不在恢复期，就不发出错误处理
						faultCode = PE_protection;	
						// 不在恢复期，发送PE没接地错误指令：					
						mTask_Fault = mTask_Fault | (0x0001 << (PE_protection - 1)); //位置1					  		
				}			  
		} else {
			  // 5秒内有改变，就是接了地;接了地就不用管
				PE_state = 1;
			  //PE_occ_times = 0;
			  // 恢复正常的PE检测监控：
				#if RTC_ON > 0
				getTimestampRTC();
				#endif
			  if(faultCode == PE_protection && PE_occ_recode > 0 && (system_time - PE_occ_recode) > PE_Recover_tmEnd){
					  // 接地就设置正常的
			      mTask_Fault = mTask_Fault & (~(0x0001 << (PE_protection - 1))); //位置0
					  main_update = 1;  //刷新一下显示灯;
				}
		}
}
#endif

// 继电器粘连检测：
#if RlyAdh_Detect_type > 0
void Get_RlyAdh_Status(){
    #if RTC_ON > 0
		getTimestampRTC();
		#endif
	  if(rlyAdh_ToZero_tm > 0 && system_time - rlyAdh_ToZero_tm > RlyAdh_Available_tm){
			  // 粘连发生：
		    rly_adhsn = 1;
			  /////////  粘连处理：///////
			  faultCode = relay_adhesion;
				mTask_Fault = mTask_Fault | (0x0001 << (relay_adhesion - 1));  //位置1
				chgForbid = relay_adhesion;  // 必须此处加禁止重启代码，否则mTask_Fault有时差，容易重启。			  
			  
			  // 继电器粘连打印出来
			  #ifdef SYS_DEBUG
				printf("Get_RlyAdh_Status  rly_adhsn = %d  %lld \n\r",rly_adhsn,rlyAdh_ToZero_tm);
				#endif
		}
}
#endif

// 充电错误恢复任务：
void protect_recover(){
		// 开始处理恢复任务
    // 错误状态中，恢复充电任务
		if(chgForbid == 0 && faultRecv_counts < faultRecv_Limit_tms && fault_recover_tm != 0 && fault_recvr_intv != 0 && faultCode > 0){
			  #if RTC_ON > 0
				getTimestampRTC();
				#endif
			  if(system_time - fault_recover_tm > fault_recvr_intv){
						protect_recover_action();
				}
		}		
}
#endif

void protect_recover_action(){
	  // 恢复充电
		if(faultCode == Istate_adjust){
				// 电流调整，状态恢复即为刷新一次错误处理;
				mTask_Fault_using = 0;
		}else{
				if(cp_data.value_cope_id == CP_6  && chgForbid == 0){
					  #if RESV_CHG_ON  > 0 || PlugCharge_And_Resv
					  startChgExternalReason.chargeControl_bit.reason_recover = 1;
					  #endif
						PWM_Duty_Set(PWM_Data.ratedDuty);
						#if volt_zero_crossing > 0
						rly_on_mark  = 1;
						#else
						Rly_on();					  
						#endif 
				}		
				// 恢复计数：
				faultRecv_counts++;
				// 状态数据恢复并重置
				#ifndef UsingFreeRTOS
				fault_recover_tm = 0;
				#endif
				// 刷新计时
				if(faultCode == low_voltage || faultCode == over_voltage){
					  #if RTC_ON > 0
						getTimestampRTC();
						#endif
					  U_CtrData.Ustt_change_tm = system_time;
				}else if(faultCode == over_current){
					  #if RTC_ON > 0
						getTimestampRTC();
						#endif
					  I_CtrData.Istt_change_tm = system_time;
				}else if(faultCode == PE_protection){
					  #if RTC_ON > 0
						getTimestampRTC();
						#endif
					  PE_occ_recode  = system_time;
				} else if(faultCode == over_tempr){
					  #if RTC_ON > 0
						getTimestampRTC();
						#endif
					  tmpr_CtrData.tmpr_change_tm = system_time;
				} 
				mTask_Fault = mTask_Fault & (~(0x0001 << (faultCode - 1))); 
				mTask_Fault_using = 0; 
				faultCodeUsingErr = 0; 
				main_update = 1;  //刷新一下显示灯; 
		}
}

#if Key1  > 0
// 按键事件处理：
void mEventKeyTreat(){
	  #ifdef SYS_DEBUG
	  printf(" ---- mEventKeyTreat  %d  ----- \r\n",key1_param.keyState);  
    #endif	
	  #if Key_SelfLock > 0
	  // 按键1事件处理：自锁按键
	  #if Non_Plug_And_Charge > 0 && key1_Ctrl_id == KeyCtrl_startChg
	  if(key1_param.keyState == key1InitLevel){
	      // 按键松开：			  
			  if(Rly_status == 1){
					  if(startChgExternalReason.chargeControl_bit.reason_btn == 1){
							  startChgExternalReason.chargeControl_bit.reason_btn = 0;	
	              // 提前关闭PWM波
                PWM_Duty_Set(DUTY_CYCLE_stop);
                #if proactive_chgStop_EN > 0	
									//延时10s关机
									stopChargeTmr = EvStopChgTimer;
									// 进入关机流程
									mTask_SW = mTask_SW | mTask_initChgStop_bit;
									#if Using_UART_LCD == LCD_4P3_UART
									// 屏幕显示关机
									lcdParam.lcd_popup_time = 10;  
									lcdParam.lcd_show_popup = lcd_popup_delay_stop;
									#endif
								#else
									Rly_off();
								#endif //#if proactive_chgStop_EN > 0
							  #ifdef SYS_DEBUG
								printf("key1Event key stop charge!!!!!   \r\n");	
								#endif
						}
			  }		
        #if Led_Key_Ctrl == 1
        // key led指示灯关闭
        led_key_off();
				#endif				
		}else{
	      // 按键按下：充电			  
			  if(startChgExternalReason.chargeControl_bit.reason_btn == 0){
						startChgExternalReason.chargeControl_bit.reason_btn = 1;
					  // 刷新并重新启动充电
            main_update = 1;
				}
	      #if Led_Key_Ctrl == 1
				// key led指示灯打开
				led_key_on();				
				#endif
		}
		#endif
	  #else
		// 非自锁按键:轻触按键
		#if Non_Plug_And_Charge > 0 && key1_Ctrl_id == KeyCtrl_startChg
		if(key1_param.keyState == 1){
			  if(startChgExternalReason.chargeControl > 0){
					  if(Rly_status == 1){
							  startChgExternalReason.chargeControl_bit.reason_btn = 0;
							  // 提前关闭PWM波
							  PWM_Duty_Set(DUTY_CYCLE_stop);
							  #if proactive_chgStop_EN > 0
									//延时10s关机
									stopChargeTmr = EvStopChgTimer;
									// 进入关机流程
									mTask_SW = mTask_SW | mTask_initChgStop_bit;
									#if Using_UART_LCD == LCD_4P3_UART
									// 屏幕显示关机
									lcdParam.lcd_popup_time = 10;  
									lcdParam.lcd_show_popup = lcd_popup_delay_stop;
									#endif
							  #else
									Rly_off();
							  #endif
							  #ifdef SYS_DEBUG
								printf("key1Event key stop charge!!!!!   \r\n");	
								#endif
						}					  
				}else{
					  startChgExternalReason.chargeControl_bit.reason_btn = 1;
						// 刷新并重新启动充电
						main_update = 1;
				}
			  #if Led_Key_Ctrl == 1
        // key led指示灯关闭
        led_key_off();
				#endif	
		}		
		#elif key1_Ctrl_id == KeyCtrl_LedPanel
		if(key1_param.keyState == 1){
			  //单击
			  #if I_rated_count > 1
			  // 单击处理
			  if(cp_data.value_cope_id == CP_12){
            I_rated_idx++;
            if(I_rated_idx >= I_rated_count)  I_rated_idx = 0;  
					  PWM_Data.ratedDuty = DUTY_CYCLE_List[I_rated_idx]; 
            #if meter485_ON > 0
						I_State_Flag.I_rated_value2 = I_rated_List2[I_rated_idx];
						#endif
						I_State_Flag.I_rated_value  = I_rated_List[I_rated_idx];						 
					  I_State_Flag.I_rated_valuef = I_rated_Listf[I_rated_idx];  
						get_I_rated_value();
						main_update++;	
            #if Rated_Save_EN > 0			
						writeData[FWD_IRated_idx].intData = I_State_Flag.I_rated_value;
						flash_write();
            #endif			
			  }
        #endif // #if I_rated_count > 1			
			  // 单击后，显示屏
			  #if Using_UART_LCD == LCD_0P42_IIC				 
				if(cp_data.value_cope_id == CP_6 && oled_reset_step > 1){
					  // 按键按以下，刷新下数据显示。需要添加按键不能太快的代码...
						#if RTC_ON > 0
						getTimestampRTC();
						#endif
					  if(system_time - key_down_recode > Key_OledShow_intv){
							  // 屏幕切换：
					      dataId = dataId + (refreshOledDataFreq - dataId % refreshOledDataFreq) + 1;
						}
						key_down_recode = system_time;
				}	
        // 重新初始化：
				#ifndef UsingFreeRTOS
				if(system_started > 0 && OledResetTm != 1){ 
					  OledResetTm = 1;
				}		
				#endif				
        #endif	
			  #ifdef SYS_DEBUG
				printf(" --------- Key_tap --------- \r\n");
				#endif
		}
		#endif // #if key1_Ctrl_id == KeyCtrl_startChg
		#if Key_longCtl > 0
		if(key1_param.keyState == -1){
			  //长按
			  #ifdef SYS_DEBUG
				printf(" --------- Key_longCtl --------- \r\n");
				#endif
		}
		#endif
		#if  Key_doubleCtl  > 0
		else if(key1_param.keyState == 2){
			  //双击
			  #ifdef SYS_DEBUG
				printf(" ---- Key_doubleCtl ----- \r\n");
				#endif
		}
		#endif
		key1_param.keyState = 0; 
	  #endif
}
#endif // #ifdef Key1 


// Led 开机效果控制;
void mTaskLedStartUp(){
	  #ifdef SYS_DEBUG
	  //printf("mTaskLedStartUp \n");
	  #endif
	  #if beep_type == beep_APM || beep_type == beep_BPM
		// 蜂鸣器任务
	  #if RTC_ON > 0
		getTimestampRTC();
		#endif
		if(system_time - led_startUp_TmRecode > startBeepTime){
			  // 蜂鸣器停止叫
			  stopBeep();
		}
		#endif
	
	  #if RTC_ON > 0
		getTimestampRTC();
		#endif
    if(system_time - led_startUp_TmRecode > ledStartUpBlinkTime){
			  // 开机等效任务
			  #ifdef Using_LedCtrl_74HC595
        Led595_start(led595AllOff);			
        #elif defined Using_LedCtrl_MCUPin
			  led_off(Led_All);
			  #endif
			  #ifndef UsingFreeRTOS
        // 结束任务；
		    mTask_SW = mTask_SW & (~mTask_ledStartUp_bit);
			  #endif
		} 
		
}

#if finger_sensor_type == Finger_HLK_ZW101_EINT
// Led开机后的初始化
void mTaskFingerInitStartUp(){
    #if RTC_ON > 0
		getTimestampRTC();
		#endif
		if(system_time - led_startUp_TmRecode > (ledStartUpHoldDarkTime + ledStartUpBlinkTime)){
				// 开机后初始化任务：
			  zw101_EINT_start();
        // 结束任务；
		    #ifndef UsingFreeRTOS
		    mTask_SW = mTask_SW & (~mTask_initStartUp_bit);
			  #endif
		}
}
#endif

#ifndef UsingFreeRTOS
// 关闭所有灯闪烁：
void mTaskLedAllBlinkStop(){
	  #ifdef SYS_DEBUG
	  // printf("mTaskLedAllBlinkStop \n");
	  #endif
    // 关闭所有的闪灯任务：
	  mTask_SW = mTask_SW & (~mTask_ledBlink_bit);
	
	  #ifdef LedCtrl_Rolling
	  // 关闭滚动
	  mTask_SW = mTask_SW & (~mTask_ledRoll_bit);
	  #endif
	
	  #ifdef Using_LedCtrl_74HC595	  
	  // 所有灯关闭
	  Led595_start(led595AllOff);
	  led_off(BL_PinId);
	  #elif CHGR_panel_Sel == CHGR_panel_B26
	  led_off(Led_All);
	  #endif
}

// 开启闪灯
void mTaskLedBlinkStart(){
	  #ifdef SYS_DEBUG
	  // printf("mTaskLedBlinkStart \r\n");
	  #endif
	  // 闪灯任务开启
	  iLed = 0;	  
	  //初始化为亮灯状态;
	  if(Led_bits > 0){
		    led_on(Led_bits);
		}		
    #ifdef Using_LedCtrl_74HC595
    if(Led595_bits != led595AllOff){
				Led595_start(Led595_bits);
		} 
		#endif	  
		ledBlink_TmRecode = system_time;
    // 开启任务：
    mTask_SW = mTask_SW | mTask_ledBlink_bit;
}

// 闪灯执行
void mTaskLedBlink(){
	  // printf("mTaskLedBlink %d \r\n",Led595_bits); 
	  // 亮灭控制数组; 0 = 亮；1 = 控制灭。
	  uint16_t ledCtrlTm[2]  = {0,0};
		ledCtrlTm[0] = ledBlinkIntv[0] * ledBlinkDuty / 100;
	  if(ledBlinkTms > 0 && iLed == ledBlinkTms * 2 - 1){
			  ledCtrlTm[1] = ledBlinkIntv[1];			  
		} else {
			  ledCtrlTm[1] = ledBlinkIntv[0] * (100-ledBlinkDuty) / 100;	
		}
		#if RTC_ON > 0
		getTimestampRTC();
		#endif
	  if(system_time - ledBlink_TmRecode > ledCtrlTm[iLed % 2]){
			  if(iLed % 2 == 0){  // 开始灭灯
					  if(Led_bits > 0){
						    if(LedOff_bits <= 0){
								    LedOff_bits = Led_bits;
								}
							  led_off(LedOff_bits);
						}
					  #ifdef Using_LedCtrl_74HC595
						if(Led595_bits != led595AllOff){
							  Led595_start(LedOff595_bits);
						}
						#endif	  
				}else if (iLed % 2 == 1){ // 开始亮灯
					  if(Led_bits > 0){
							  led_on(Led_bits);
						}						
						#ifdef Using_LedCtrl_74HC595
						if(Led595_bits != led595AllOff){
							  Led595_start(Led595_bits); 
						}							
						#endif		
				}	
			  iLed++;
				if(iLed == ledBlinkTms * 2){
					  iLed = 0;
				}
				#if RTC_ON > 0
				getTimestampRTC();
				#endif
        ledBlink_TmRecode = system_time;
		} 	
}

#ifdef LedCtrl_Rolling
// 滚动效果：滚动和闪烁不能同时存在。因为共用了iLed + ledBlink_TmRecode;
void mTaskLedRollStart(){
	  #ifdef SYS_DEBUG
	  printf("mTaskLedRollStart \r\n");
	  #endif
	  // 闪灯任务开启
	  iLed = 0;
    #if RTC_ON > 0
		getTimestampRTC();
		#endif
	  ledBlink_TmRecode = system_time;
    //初始状态 = 状态1  
    //Led595_bits = 0x1E; //0001 1110,第3个是1
	  #ifdef Led7Pin_ABCDEFG
	  Led595_start(led595_7roll4_7);
	  #elif defined Led5Pin_ABCDE
	  Led595_start(led595_5roll3_5);
	  #endif
    // 开启任务：
    mTask_SW = mTask_SW | mTask_ledRoll_bit;
}

void mTaskLedRollBlink(){
    #if RTC_ON > 0
		getTimestampRTC();
		#endif
	  if(system_time - ledBlink_TmRecode > ledBlinkIntv[0]){
			  //#if CHGR_panel_Sel == CHGR_panel_B20
				// 滚顶效果算法：128,64,32,16,8,4,2,1选相邻3个或4个数字相加，依次类推。
        #ifdef Led7Pin_ABCDEFG			
			  switch(iLed){
				case 1:        
						Led595_bits = led595_7roll4_1; //120  
						break;
				case 2:         							
           	Led595_bits = led595_7roll4_2; //240		
						break;
				case 3:         
						Led595_bits = led595_7roll4_3; //226
						break;
				case 4:         
						Led595_bits = led595_7roll4_4; //198
						break;
			  case 5:         						
			      Led595_bits = led595_7roll4_5; //142
						break;
        case 6:          
						Led595_bits = led595_7roll4_6; //30
						break;				
				case 7:          
				    Led595_bits = led595_7roll4_7; //60
            iLed = 0;  
						break;
		    }			  
			  /*
	      if(iLed == 3){
					  Led595_bits = 0xE2;
				}else if(iLed == 4){
						Led595_bits = 0xC6;
				}else if(iLed == 5){
						Led595_bits = 0x8E;					  
				}else if(iLed == 6){
						Led595_bits = 0x1E;
					  iLed = 0;
				} else {
					  Led595_bits = Led595_bits << 1;
				}	
        */			
				#elif defined Led5Pin_ABCDE				
				switch(iLed){
				case 1:          
						Led595_bits = led595_5roll3_1; //112  
						break;
				case 2:          
						Led595_bits = led595_5roll3_2; //224				
						break;
				case 3:         
						Led595_bits = led595_5roll3_3; //200
						break;
				case 4:         
						Led595_bits = led595_5roll3_4; //152
						break;
				case 5:          
						Led595_bits = led595_5roll3_5; //56
            iLed = 0;  
						break;
		    }
				#elif defined Using_LedCtrl_MCUPin
				switch(iLed){
				case 1:          
						Led_idx_scroll = led595On_A;   
						break;
				case 2:          
						Led_idx_scroll = led595On_B; 			
						break;
				case 3:         
						Led_idx_scroll = led595On_C; 						
            iLed = 0;  
						break;
		    }
				/*
			  if(iLed == 3){
						Led595_bits = 0xC8;
				}else if(iLed == 4){
						Led595_bits = 0x98;
				}else if(iLed == 5){
						Led595_bits = 0x38;
            iLed = 0;
				} else {
					  Led595_bits = Led595_bits << 1;
				}
				*/
	      #endif
				#ifdef Using_LedCtrl_MCUPin
				led_off(Led_All);
				led_on(Led_idx_scroll);
				#else
				Led595_start(Led595_bits);
		    #endif		

        iLed++;	
        #if RTC_ON > 0
				getTimestampRTC();
				#endif				
				ledBlink_TmRecode = system_time;            			
		}		
}
#endif

#endif // #ifndef UsingFreeRTOS

////////////////// 处理串口发来的数据 ////////////////////////
#if using_uart1 > 0
void treatUart1Info(){    	
	  #ifdef SYS_DEBUG	
    int16_t i = 0;  
	  printf(" Uart1: \r\n");		
	  for(i = 0; i < rxBuf1_size; i++){
			  printf(" 0x%02x ",uart1Ctrl.uartRxDatas[i]);
		}
    printf(" \r\n");		
		#endif
		
		// 处理业务：
		#if BleWifi_Uart_Using == BleWifi_Uart1 && BleWifi_type == BleWifi_Ai_WB2
		uart_bleWifi_treat();
		#endif
    uart1Ctrl.recv_ctrl = 0;		
}
#endif
#if using_uart2 > 0
// RS485部分：
void treatUart2Info(){
	  #if meter485_ON > 0
	  meter485_Data tmp;
	  #if meter485_CRC_ON  > 0
	  CRC16_Data    crcTmp;
	  #endif
	  uint8_t k = 0;
	  #endif	  
	  /*
	  #ifdef SYS_DEBUG
	  uint16_t i = 0;
	  printf(" Uart2: \r\n");		
	  for(i = 0; i < rxBuf2_size; i++){
			  printf(" 0x%02x ",uart2Ctrl.uartRxDatas[i]);
		}
    printf(" \r\n");		
		#endif
	  */			  
    uart2Ctrl.recv_ctrl = 0;
    // RS485 数据处理：
		#if meter485_ON > 0
		#if meter485_CRC_ON  > 0
			#if PowerSupplyPhase == 1
			  if(uart2Ctrl.uartRxDatas[2] == meter485_Sect1_dataLen)  crcTmp.dataInt = CRC_GetModbus16(uart2Ctrl.uartRxDatas,meter485_Sect1_CRCLen);
				else if(uart2Ctrl.uartRxDatas[2] == meter485_Sect2_dataLen) crcTmp.dataInt = CRC_GetModbus16(uart2Ctrl.uartRxDatas,meter485_Sect2_CRCLen);         				
     	#elif PowerSupplyPhase == 3
				crcTmp.dataInt = CRC_GetModbus16(uart2Ctrl.uartRxDatas,meter485_CRCLen);
			#endif	
    #endif
    #if PowerSupplyPhase == 1
    if(uart2Ctrl.uartRxDatas[2] == meter485_Sect1_dataLen){
		    #if meter485_CRC_ON  > 0
			  if(!(crcTmp.dataArray[0] == uart2Ctrl.uartRxDatas[meter485_Sect1_CRCLen] && crcTmp.dataArray[1] == uart2Ctrl.uartRxDatas[meter485_Sect1_CRCLen+1]))  return;
			  #endif
				for(k = 0; k < 4; k++){
					  tmp.dataArray[k] = uart2Ctrl.uartRxDatas[6 - k + mt485_UA];
				}
				mt485_Data.U_RMS = tmp.dataFloat;
				for(k = 0; k < 4; k++){
					  tmp.dataArray[k] = uart2Ctrl.uartRxDatas[6 - k + mt485_IA * 2];
				}
				mt485_Data.I_RMS = tmp.dataFloat;
				for(k = 0; k < 4; k++){
					  tmp.dataArray[k] = uart2Ctrl.uartRxDatas[6 - k + mt485_PWRA * 2];
				}
				mt485_Data.P_actv = tmp.dataFloat;
				for(k = 0; k < 4; k++){
					  tmp.dataArray[k] = uart2Ctrl.uartRxDatas[6 - k + mt485_PapT * 2];
				}
				mt485_Data.Papt = tmp.dataFloat;
				
				// 智能电表整数判据
				uiValues2.U_value = mt485_Data.U_RMS * 10;
				uiValues2.I_value = mt485_Data.I_RMS * 100;
				
        // 切换至智能电表数据
				//printf(" %u   %f  \r\n",uiValues.U_value,fabs(mt485_Data.U_RMS * mt485_Data.I_RMS - mt485_Data.P_actv));
				if(uiValues2.U_value > 10 && fabs(mt485_Data.U_RMS * mt485_Data.I_RMS - mt485_Data.Papt) < 50){					  
						mt485_Data.meterReady = 1;
				}	
				#if RTC_ON > 0
				getTimestampRTC();
				#endif
				mt485RdTm = system_time;
	  }else if(uart2Ctrl.uartRxDatas[2] == meter485_Sect2_dataLen){
		    #if meter485_CRC_ON  > 0
			  if(!(crcTmp.dataArray[0] == uart2Ctrl.uartRxDatas[meter485_Sect2_CRCLen] && crcTmp.dataArray[1] == uart2Ctrl.uartRxDatas[meter485_Sect2_CRCLen+1]))  return;
			  #endif
				for(k = 0; k < 4; k++){
					  tmp.dataArray[k] = uart2Ctrl.uartRxDatas[6 - k];
				}
				mt485_Data.QOE = tmp.dataFloat * 100;
				
		}
    #elif PowerSupplyPhase == 3
		if(uart2Ctrl.uartRxDatas[2] == meter485_dataLen){
			  #if meter485_CRC_ON  > 0
			  if(!(crcTmp.dataArray[0] == uart2Ctrl.uartRxDatas[meter485_CRCLen] && crcTmp.dataArray[1] == uart2Ctrl.uartRxDatas[meter485_CRCLen+1]))  return;
			  #endif
			  for(k = 0; k < 4; k++){
					  tmp.dataArray[k] = uart2Ctrl.uartRxDatas[6 - k + mt485_UA];
				}
				mt485_Data.U_RMS = tmp.dataFloat;
				for(k = 0; k < 4; k++){
					  tmp.dataArray[k] = uart2Ctrl.uartRxDatas[6 - k + mt485_IA * 2];
				}
				mt485_Data.I_RMS = tmp.dataFloat;
				for(k = 0; k < 4; k++){
					  tmp.dataArray[k] = uart2Ctrl.uartRxDatas[6 - k + mt485_PWRA * 2];
				}
				mt485_Data.P_actv = tmp.dataFloat * 1000;
				for(k = 0; k < 4; k++){
					  tmp.dataArray[k] = uart2Ctrl.uartRxDatas[6 - k + mt485_PapT * 2];
				}
				mt485_Data.Papt = tmp.dataFloat * 1000;	    
				for(k = 0; k < 4; k++){
					  tmp.dataArray[k] = uart2Ctrl.uartRxDatas[6 - k + mt485_PTFCnt * 2];
				}
				mt485_Data.QOE = tmp.dataFloat * 100;				
				#if PowerSupplyPhase == 3
				for(k = 0; k < 4; k++){
					  tmp.dataArray[k] = uart2Ctrl.uartRxDatas[6 - k + mt485_UB * 2];
				}
				mt485_Data.UB_RMS = tmp.dataFloat;
				for(k = 0; k < 4; k++){
					  tmp.dataArray[k] = uart2Ctrl.uartRxDatas[6 - k + mt485_UC * 2];
				}
				mt485_Data.UC_RMS = tmp.dataFloat;
				for(k = 0; k < 4; k++){
					  tmp.dataArray[k] = uart2Ctrl.uartRxDatas[6 - k + mt485_IB * 2];
				}
				mt485_Data.IB_RMS = tmp.dataFloat;
				for(k = 0; k < 4; k++){
					  tmp.dataArray[k] = uart2Ctrl.uartRxDatas[6 - k + mt485_IC * 2];
				}
				mt485_Data.IC_RMS = tmp.dataFloat;
				for(k = 0; k < 4; k++){
					  tmp.dataArray[k] = uart2Ctrl.uartRxDatas[6 - k + mt485_PWRB * 2];
				}
				mt485_Data.PB_actv = tmp.dataFloat * 1000;
				for(k = 0; k < 4; k++){
					  tmp.dataArray[k] = uart2Ctrl.uartRxDatas[6 - k + mt485_PWRC * 2];
				}
				mt485_Data.PC_actv = tmp.dataFloat * 1000;
				for(k = 0; k < 4; k++){
					  tmp.dataArray[k] = uart2Ctrl.uartRxDatas[6 - k + mt485_PWRT * 2];
				}
				mt485_Data.PT_actv = tmp.dataFloat * 1000;				    				
				#endif //PowerSupplyPhase == 3
				// 智能电表整数判据
				uiValues2.U_value = mt485_Data.U_RMS * 10;
				uiValues2.I_value = mt485_Data.I_RMS * 100;
				#if PowerSupplyPhase == 3
				uiValues2.UB_value = mt485_Data.UB_RMS * 10;
				uiValues2.IB_value = mt485_Data.IB_RMS * 100;
				uiValues2.UC_value = mt485_Data.UC_RMS * 10;
				uiValues2.IC_value = mt485_Data.IC_RMS * 100;				
				#endif
        // 切换至智能电表数据	
        if(uiValues2.U_value > 0 && fabs(mt485_Data.U_RMS * mt485_Data.I_RMS - mt485_Data.P_actv) < 50){
					  mt485_Data.meterReady = 1;						
				}	
				#if RTC_ON > 0
				getTimestampRTC();
				#endif
				mt485RdTm = system_time;
		}
		#endif // #elif PowerSupplyPhase == 3
		#endif // #if meter485_ON > 0 		
		// rdMeter485Busy = 0;
}
#endif

#if using_uart3 > 0
void treatUart3Info(){
    #ifdef SYS_DEBUG
    uint16_t i = 0;
	  #endif	  	
	  if(uart3Ctrl.uartRxDatas[0] == 'B' && uart3Ctrl.uartRxDatas[1] == 'e' && uart3Ctrl.uartRxDatas[2] == 'e' && uart3Ctrl.uartRxDatas[3] == 'p' && uart3Ctrl.uartRxDatas[4] == '1'){
			  // 指令[[Beep1]]：启动蜂鸣器叫2下;
			  #if beep_type > 0 && (Using_UART_LCD == LCD_4P3_UART || beep_type == beep_APM || beep_type == beep_BPM)
			  beep_start(2,100,200);
			  #endif
		}
		#if LOG_ON > 0
		else if(uart3Ctrl.uartRxDatas[0] == 'R' && uart3Ctrl.uartRxDatas[1] == 'd' && uart3Ctrl.uartRxDatas[2] == 'L' && uart3Ctrl.uartRxDatas[3] == 'o' && uart3Ctrl.uartRxDatas[4] == 'g'){
			  // 指令：[[RdLog]] = 输出log信息		    
		    if(uart3Ctrl.uart_idx >= 8){
					  #if Nor_Flash > 0
					  if(uart3Ctrl.uartRxDatas[5] == '-' && uart3Ctrl.uartRxDatas[6] == '-' && uart3Ctrl.uartRxDatas[7] == '-'){
							  // 向前翻页							  
							  if(log_sect_read_id > 0) log_sect_read_id--;
						}else if(uart3Ctrl.uartRxDatas[5] == '+' && uart3Ctrl.uartRxDatas[6] == '+' && uart3Ctrl.uartRxDatas[7] == '+'){
							  // 向后翻页
							  if(log_sect_read_id < Total_LogData_Sects) log_sect_read_id++;
						}else if(uart3Ctrl.uartRxDatas[5] == 'C' && uart3Ctrl.uartRxDatas[6] == 'R' && uart3Ctrl.uartRxDatas[7] == 'T'){
							  // 显示当前页
							  log_sect_read_id = log_sect_save_id;							  
						} else {
							  uint8_t  pageIdStr[3];
							  uint16_t  pageIdTmp;
							  pageIdStr[0] = uart3Ctrl.uartRxDatas[5];
							  pageIdStr[1] = uart3Ctrl.uartRxDatas[6];
							  pageIdStr[2] = uart3Ctrl.uartRxDatas[7];
							  pageIdTmp = strArrToInt(pageIdStr,3);
							  if(pageIdTmp <= Total_LogData_Sects) log_sect_read_id = pageIdTmp;
						}
						printPageLogs();
						#endif
				} else {
					  printLogs();
				}
		}		
		#endif
		#if RESV_CHG_ON  > 0
		else if(uart3Ctrl.uartRxDatas[0] == 'R' && uart3Ctrl.uartRxDatas[1] == 'E' && uart3Ctrl.uartRxDatas[2] == 'S' && uart3Ctrl.uartRxDatas[3] == 'V' && uart3Ctrl.uartRxDatas[4] == 'G'){
			  // 预约充电指令：[[RESVG]]		    
        resv_data.resv_start_point =  ((uint64_t)uart3Ctrl.uartRxDatas[5] << 56) + ((uint64_t)uart3Ctrl.uartRxDatas[6] << 48) + \
		                                  ((uint64_t)uart3Ctrl.uartRxDatas[7] << 40) + ((uint64_t)uart3Ctrl.uartRxDatas[8] << 32) + \
		                                  ((uint64_t)uart3Ctrl.uartRxDatas[9] << 24) + ((uint64_t)uart3Ctrl.uartRxDatas[10] << 16) + \
		                                  ((uint64_t)uart3Ctrl.uartRxDatas[11] << 8) + uart3Ctrl.uartRxDatas[12];
		    resv_data.resv_time[0]     =  ((uint16_t)uart3Ctrl.uartRxDatas[13] << 8) + uart3Ctrl.uartRxDatas[14];
		    resv_data.resv_time[1]     =  ((uint16_t)uart3Ctrl.uartRxDatas[15] << 8) + uart3Ctrl.uartRxDatas[16];
		    resv_data.resv_time[2]     =  ((uint16_t)uart3Ctrl.uartRxDatas[17] << 8) + uart3Ctrl.uartRxDatas[18];
		    resv_data.resv_time[3]     =  ((uint16_t)uart3Ctrl.uartRxDatas[19] << 8) + uart3Ctrl.uartRxDatas[20];
		    resv_data.resv_week.week   = uart3Ctrl.uartRxDatas[21];
				// 保存预约参数
		    writeData[resv_sp_idxH].intData = (uint32_t)(resv_data.resv_start_point >> 32);
		    writeData[resv_sp_idxL].intData = (uint32_t)(resv_data.resv_start_point & 0x0000ffff);
		    writeData[resv_t1_idx].intData  = ((uint32_t)resv_data.resv_time[0] << 16) + resv_data.resv_time[1];
		    writeData[resv_t2_idx].intData  = ((uint32_t)resv_data.resv_time[2] << 16) + resv_data.resv_time[3];
		    writeData[resv_wkEn_idx].charData[0] = resv_data.resv_week.week;
		    // 保存
		    flash_write();
	  }
		#endif
		else if(uart3Ctrl.uartRxDatas[0] == 'C' && uart3Ctrl.uartRxDatas[1] == 'h' && uart3Ctrl.uartRxDatas[2] == 'g' && uart3Ctrl.uartRxDatas[3] == 'I' && uart3Ctrl.uartRxDatas[4] == 'd'){
			  // 变更插座ID：
		    if(uart3Ctrl.uart_idx >= 9){
					  Chgr_Name[0] = uart3Ctrl.uartRxDatas[5];
					  Chgr_Name[1] = uart3Ctrl.uartRxDatas[6];
					  Chgr_Name[2] = uart3Ctrl.uartRxDatas[7];
					  Chgr_Name[3] = uart3Ctrl.uartRxDatas[8];
					  if(uart3Ctrl.uart_idx >= 10){
							  Chgr_Name[4] = uart3Ctrl.uartRxDatas[9];
						}
						if(uart3Ctrl.uart_idx >= 11){
							  Chgr_Name[5] = uart3Ctrl.uartRxDatas[10];
						}
						if(uart3Ctrl.uart_idx >= 12){
							  Chgr_Name[6] = uart3Ctrl.uartRxDatas[11];
						}
						if(uart3Ctrl.uart_idx >= 13){
							  Chgr_Name[7] = uart3Ctrl.uartRxDatas[12];
						}
						// 保存id
						writeData[Chgr_Id_Int_H].charData[0] = Chgr_Name[0];
						writeData[Chgr_Id_Int_H].charData[1] = Chgr_Name[1];
						writeData[Chgr_Id_Int_H].charData[2] = Chgr_Name[2];
						writeData[Chgr_Id_Int_H].charData[3] = Chgr_Name[3];
						writeData[Chgr_Id_Int_L].charData[0] = Chgr_Name[4];
						writeData[Chgr_Id_Int_L].charData[1] = Chgr_Name[5];
						writeData[Chgr_Id_Int_L].charData[2] = Chgr_Name[6];
						writeData[Chgr_Id_Int_L].charData[3] = Chgr_Name[7];
						flash_write();
				}
	  }
		#ifdef SYS_DEBUG		  
	  for(i = 0; i < uart3Ctrl.uart_idx + 1; i++){
			  printf("%c",uart3Ctrl.uartRxDatas[i]);
		}
    printf(" \r\n");		
		#endif	 		
		uart3Ctrl.recv_ctrl = 0;		
}
#endif


#if using_uart4 > 0
void treatUart4Info(){
	  #ifdef SYS_DEBUG
    uint16_t i = 0;
	  #endif	  
	  #if finger_sensor_type > 0
    if(uart4Ctrl.uartRxDatas[len4_bit + len4_bit_num - 2] == 0x00){
	     union Finger2ByteData check_sum;
			 check_sum.shortData = getCheckSum_16Bit(uart4Ctrl.uartRxDatas, len4_bit - 3, uart4Ctrl.uart_idx - 1);
			 if(check_sum.charArrData[1] == uart4Ctrl.uartRxDatas[uart4Ctrl.uart_idx - 1] && check_sum.charArrData[0] == uart4Ctrl.uartRxDatas[uart4Ctrl.uart_idx]){
				   // 应答参数的开始字节：
				   uint16_t start_idx = len4_bit + len4_bit_num - 1;
           if(fingerCtrl.fingerCMD == PS_ReadSysPara){
							 // 获取指纹识别的参数：
							 fingerInfo.finger_register_times.charArrData[1] = uart4Ctrl.uartRxDatas[start_idx]; 
							 fingerInfo.finger_register_times.charArrData[0] = uart4Ctrl.uartRxDatas[start_idx + 1]; 
							 fingerInfo.finger_template_size.charArrData[1] = uart4Ctrl.uartRxDatas[start_idx + 2]; 
							 fingerInfo.finger_template_size.charArrData[0] = uart4Ctrl.uartRxDatas[start_idx + 3];		 		   
							 fingerInfo.finger_lib_size.charArrData[1] = uart4Ctrl.uartRxDatas[start_idx + 4];
							 fingerInfo.finger_lib_size.charArrData[0] = uart4Ctrl.uartRxDatas[start_idx + 5];				   
							 fingerInfo.finger_score_level.charArrData[1] = uart4Ctrl.uartRxDatas[start_idx + 6];
							 fingerInfo.finger_score_level.charArrData[0] = uart4Ctrl.uartRxDatas[start_idx + 7];				   
							 fingerInfo.finger_package_size.charArrData[1] = uart4Ctrl.uartRxDatas[start_idx + 12];
							 fingerInfo.finger_package_size.charArrData[0] = uart4Ctrl.uartRxDatas[start_idx + 13];				   
							 fingerInfo.finger_Baud_Rate.charArrData[1] = uart4Ctrl.uartRxDatas[start_idx + 14];
							 fingerInfo.finger_Baud_Rate.charArrData[0] = uart4Ctrl.uartRxDatas[start_idx + 15];
							 #ifdef SYS_DEBUG
							 printf("finger param: regtm = %d, tmpSize = %d, ",fingerInfo.finger_register_times.shortData,fingerInfo.finger_template_size.shortData);
							 printf(" libSize = %d,  sr = %d,  ",fingerInfo.finger_lib_size.shortData,fingerInfo.finger_score_level.shortData);
							 printf(" pkSize = %d,  baud = %d,   \r\n",fingerInfo.finger_package_size.shortData,fingerInfo.finger_Baud_Rate.shortData);
							 #endif
						   fingerCtrl.finger_busy = 0;  // 此任务步骤结束;
						   #if finger_sensor_type == Finger_HLK_ZW101_EINT
						   fingerCtrl.finger_step = 0;
							 #else
							 fingerCtrl.finger_step = 2;
							 #endif
					 } else if(fingerCtrl.fingerCMD == PS_AutoEnroll){
						    union Finger2ByteData reg_result;
						    reg_result.charArrData[1] = uart4Ctrl.uartRxDatas[start_idx];
							  reg_result.charArrData[0] = uart4Ctrl.uartRxDatas[start_idx + 1];
						    if(reg_result.charArrData[1] == 0x00 && reg_result.charArrData[0] == 0x00){
									  // 提示开始输入指纹
									  #if beep_type > 0 && (Using_UART_LCD == LCD_4P3_UART || beep_type == beep_APM || beep_type == beep_BPM)
										beep_start(1,600,200);	
										#endif	
						    } else if(reg_result.charArrData[1] == 0x02 && reg_result.charArrData[0] < finger_reg_times){
									  // 录入成功
									  #if beep_type > 0 && (Using_UART_LCD == LCD_4P3_UART || beep_type == beep_APM || beep_type == beep_BPM)
										beep_start(1,200,200);
										#endif									  
								} else if(reg_result.charArrData[1] == 0x06 && reg_result.charArrData[0] == 0xf2){
									  // 录入结束
									  #if beep_type > 0 && (Using_UART_LCD == LCD_4P3_UART || beep_type == beep_APM || beep_type == beep_BPM)
										beep_start(2,200,100);									  
										#endif
									  fingerCtrl.finger_busy = 1;
								}
					 } else if(fingerCtrl.fingerCMD == PS_AutoIdentify){
						   if(uart4Ctrl.uartRxDatas[start_idx] == 0x00 && uart4Ctrl.uartRxDatas[start_idx + 1] == led595AllOff && uart4Ctrl.uartRxDatas[start_idx + 2] == led595AllOff){
								   // 提示输入指纹，以便验证; 这里不做任何动作								   
							 } else if(uart4Ctrl.uartRxDatas[start_idx] == 0x05) {
									 fingerInfo.finger_search_id.charArrData[1] = uart4Ctrl.uartRxDatas[start_idx + 1];
									 fingerInfo.finger_search_id.charArrData[0] = uart4Ctrl.uartRxDatas[start_idx + 2];
								   if(fingerInfo.finger_search_id.shortData != 0xffff){
										    // 找到指纹所有着：启动充电
									      #if beep_type > 0 && (Using_UART_LCD == LCD_4P3_UART || beep_type == beep_APM || beep_type == beep_BPM)
												beep_start(1,200,100);
												#endif
										    fingerCtrl.finger_busy = 0;
										    if(externalIntv > 0) return;
										    externalIntv = externalIntv_default;
										    // 指纹充电控制
										    if(startChgExternalReason.chargeControl > 0){
														if(Rly_status == 1){
																startChgExternalReason.chargeControl_bit.reason_finger = 0;
																// 提前关闭PWM波
																PWM_Duty_Set(DUTY_CYCLE_stop);
															  #if proactive_chgStop_EN > 0	
																	//延时10s关机
																	stopChargeTmr = EvStopChgTimer;
																	// 进入关机流程
																	mTask_SW = mTask_SW | mTask_initChgStop_bit;
																	#if Using_UART_LCD == LCD_4P3_UART
																		// 屏幕显示关机
																		lcdParam.lcd_popup_time = 10;  
																		lcdParam.lcd_show_popup = lcd_popup_delay_stop;
																	#endif
															  #else //#if proactive_chgStop_EN > 0
															    Rly_off();
                                #endif //#if proactive_chgStop_EN > 0	 											
														}					  
														#ifdef SYS_DEBUG
														printf("finger stop charge!!!!!   \r\n");	
														#endif
												}else{
														startChgExternalReason.chargeControl_bit.reason_finger = 1;
														// 刷新并重新启动充电
														main_update = 1;
													  #ifdef SYS_DEBUG
														printf("finger start charge!!!!!  %u   \r\n",startChgExternalReason.chargeControl);	
														#endif
												}
									 } 								 
							 }
					 } else {
						   #ifdef SYS_DEBUG
							 printf(" fingerCtrl.fingerCMD = 0x%02x  %d  \r\n",fingerCtrl.fingerCMD,fingerCtrl.fingerCMD);		
							 #endif
					 }
			 } else {
				   #ifdef SYS_DEBUG
					 printf(" check sum error = 0x%04x  %d  \r\n",check_sum.shortData,check_sum.shortData);		
			     #endif	 
			 }
		} else {
			  // 错误处理
			  fingerCtrl.finger_errCode = uart4Ctrl.uartRxDatas[len4_bit + len4_bit_num - 2];
			  #ifdef SYS_DEBUG
				printf(" fingerCtrl.finger_errCode = 0x%02x   \r\n",fingerCtrl.finger_errCode);		
				#endif
        if(fingerCtrl.fingerCMD == PS_AutoEnroll && fingerCtrl.finger_errCode != 0x00){
					  fingerCtrl.finger_busy = 1;
					  if(fingerCtrl.finger_errCode == 0x22){
							  // id被占用
							  fingerCtrl.finger_id.shortData = fingerCtrl.finger_id.shortData + 1;
						} else if(fingerCtrl.finger_errCode == 0x0b){
							  fingerCtrl.finger_id.shortData = 0;
						}
				}else if(fingerCtrl.fingerCMD == PS_AutoIdentify && fingerCtrl.finger_errCode == 0x09){
					  #if beep_type > 0 && (Using_UART_LCD == LCD_4P3_UART || beep_type == beep_APM || beep_type == beep_BPM)
						beep_start(1,800,100);
						#endif
					  fingerCtrl.finger_busy = 0;
				}		
		}
		#endif // finger_sensor_type > 0
	  #ifdef SYS_DEBUG		  
	  for(i = 0; i < uart4Ctrl.uart_idx + 1; i++){
			  printf("%02x ",uart4Ctrl.uartRxDatas[i]);
		}
    printf(" \r\n");		
		#endif	 
		uart4Ctrl.recv_ctrl = 0;
}
#endif
#if using_uart5 > 0
void treatUart5Info(){
	  #ifdef SYS_DEBUG
	  uint16_t i = 0;
	  for(i = 0; i < 50; i++){
			  printf("%c",uart5Ctrl.uartRxDatas[i]);
		}
    printf(" \r\n");		
		#endif
    
    // 处理业务：
		#if BleWifi_Uart_Using == BleWifi_Uart5 && BleWifi_type == BleWifi_Ai_WB2
		uart_bleWifi_treat();
		#endif		
    uart5Ctrl.recv_ctrl = 0;		
}
#endif

//////////////////////////////////////// 处理blewifi设备发来信息 ///////////////////////////////////////////////
#if BleWifi_type == BleWifi_Ai_WB2
void uart_bleWifi_treat(){	
	  int16_t i = 0;
	  // 查询回复的处理
	  printf(" %d \r\n",bleWiFi_Data.bw_bleSet_id);
		if(bleWiFi_Data.bw_bleSet_id == bleWifi_set_bleMode || bleWiFi_Data.bw_query_id == 1){
			  i = isContainArr(bw_ctrl_uart.uartRxDatas,bleWifi_reply_checkBleMode,rxBuf1_size,bleWifi_reply_checkBleMode_size);
			  
			  if(i >= 0){
					  bw_arrTmp[0] = bw_ctrl_uart.uartRxDatas[i+2];
					  bleWiFi_Data.bw_bleMode = strArrToInt(bw_arrTmp,1);
				}
		}else if(bleWiFi_Data.bw_bleSet_id == bleWifi_set_wifiMode || bleWiFi_Data.bw_query_id == 1){
			  i = isContainArr(bw_ctrl_uart.uartRxDatas,bleWifi_reply_checkWifiMode,rxBuf1_size,bleWifi_reply_checkWifiMode_size);
			  if(i >= 0){
					  bw_arrTmp[0] = bw_ctrl_uart.uartRxDatas[i+2];
					  bleWiFi_Data.bw_wifiMode = strArrToInt(bw_arrTmp,1);
				}
		}else if(bleWiFi_Data.bw_bleSet_id == bleWifi_set_bleName || bleWiFi_Data.bw_query_id == 1){
			  i = isContainArr(bw_ctrl_uart.uartRxDatas,bleWifi_reply_checkBleAddr,rxBuf1_size,bleWifi_reply_checkBleAddr_size);
			  if(i >= 0){			  
					  bw_arrTmp[0] = bw_ctrl_uart.uartRxDatas[i+2];
					  bw_arrTmp[1] = bw_ctrl_uart.uartRxDatas[i+3];
					  bw_arrTmp[2] = bw_ctrl_uart.uartRxDatas[i+4];
					  bw_arrTmp[3] = bw_ctrl_uart.uartRxDatas[i+5];
					  bw_arrTmp[4] = bw_ctrl_uart.uartRxDatas[i+6];
					  bw_arrTmp[5] = bw_ctrl_uart.uartRxDatas[i+7];
					  bw_arrTmp[6] = bw_ctrl_uart.uartRxDatas[i+8];
					  bw_arrTmp[7] = bw_ctrl_uart.uartRxDatas[i+9];
					  bw_arrTmp[8] = bw_ctrl_uart.uartRxDatas[i+10];
					  bw_arrTmp[9] = bw_ctrl_uart.uartRxDatas[i+11];
					  bw_arrTmp[10] = bw_ctrl_uart.uartRxDatas[i+12];
					  bw_arrTmp[11] = bw_ctrl_uart.uartRxDatas[i+13];
					  hexCharArrToHex(bw_arrTmp,12,bleWiFi_Data.bw_mac);
				}
		}else if(bleWiFi_Data.bw_query_id == 1){
			  i = isContainArr(bw_ctrl_uart.uartRxDatas,bleWifi_reply_checkSSI,rxBuf1_size,bleWifi_reply_checkSSI_size);
			  if(i >= 0){
					  bw_arrTmp[0] = bw_ctrl_uart.uartRxDatas[i+3];
					  bw_arrTmp[1] = bw_ctrl_uart.uartRxDatas[i+4];
					  bleWiFi_Data.bw_wifiSSI = -1 * strArrToInt(bw_arrTmp,2);
				}
		}
		// 调试输出：
		printf(" %d; %d; %d; %x %x %x %x %x %x \r\n",bleWiFi_Data.bw_bleMode,bleWiFi_Data.bw_wifiMode,bleWiFi_Data.bw_wifiSSI,\
		        bleWiFi_Data.bw_mac[0],bleWiFi_Data.bw_mac[1],bleWiFi_Data.bw_mac[2],bleWiFi_Data.bw_mac[3],\
		        bleWiFi_Data.bw_mac[4],bleWiFi_Data.bw_mac[5]);
}
#endif

//////////////////////////////////////// 日志相关函数 ///////////////////////////////////////////////
#if LOG_ON > 0 
// log数据加入
uint8_t log_data_append(struct log_Item logAppend){ 
    if(Log_Saved_Sum > 1){ 
			  if(logAppend.logGrade == writeLogData[Log_Saved_Sum - 1].logData.logGrade  \
					 && logAppend.logEvent == writeLogData[Log_Saved_Sum - 1].logData.logEvent \
				   && logAppend.logEvtData == writeLogData[Log_Saved_Sum - 1].logData.logEvtData) return 0;	
		}	
	  if(Log_Saved_Sum >= Logs_Data_size){  
			  #if Nor_Flash > 0  
			  // 满了就保存：	      
		    flash_log_write();  
			  // 保存好，就重新开启一页;  
			  Log_Saved_Sum = 1;  
			  log_sect_save_id++;  
			  if(log_sect_save_id >= Total_LogData_Sects) log_sect_save_id = 0;  
			  writeData[FWD_LogSavePageId_idx].intData = log_sect_save_id;  
			  flash_write();        			
			  #else  
			  uint16_t i = 0;	  
				for(i = 0; i < Log_Saved_Sum - 1; i++){						
						writeLogData[i].logData = writeLogData[i + 1].logData;  
				}	 
        #endif			
		} else {
			  Log_Saved_Sum++;  
		}		
		writeLogData[Log_Saved_Sum - 1].logData = logAppend;
    return 1;		
}

// log数据打印出来
void printLogs(){
	 uint16_t i = 0;	
	 #if Nor_Flash > 0
	 printf("LOGS:%d,%d:\r\n",log_sect_save_id, Log_Saved_Sum);
   #else
	 printf("LOGS:%d:\r\n", Log_Saved_Sum);
   #endif	
	 for(i = 0; i < Log_Saved_Sum; i++){
		  printf("[ %d ]:",writeLogData[i].logData.occTime); 
		  printf(" %d, ",writeLogData[i].logData.logGrade); 
		  printf(" %d, ",writeLogData[i].logData.logEvent); 
		  printf(" %d  \r\n",writeLogData[i].logData.logEvtData); 
	 }
}

// 按页读取norflash中数据
#if Nor_Flash > 0
void printPageLogs(){
	 uint16_t i = 0;	
	 uint16_t log_read_max = 0;
	 if(log_sect_read_id == log_sect_save_id){
			log_read_max = Log_Saved_Sum;			  
	 } else {
			log_read_max = Logs_Data_size;			  
	 }
	 if(log_read_max <= 0) return;
	 // 读取某页
	 flash_logPage_read(log_read_max);
	 // 打印
	 printf("==== logRead: %d  %d ==== \r\n", log_read_max,log_sect_read_id);  
	 for(i = 0; i < log_read_max; i++){ 
		  printf("[ %d ]:",readLogData[i].logData.occTime); 
		  printf(" %d, ",readLogData[i].logData.logGrade); 
		  printf(" %d, ",readLogData[i].logData.logEvent); 
		  printf(" %d  \r\n",readLogData[i].logData.logEvtData); 
	 }
	 printf("=====  LOGS List Enc  ===== \r\n"); 
}
#endif // Nor_Flash > 0

#endif // #if LOG_ON > 0

///////////////////////////////////// 功率曲线数据处理相关函数 ///////////////////////////////////////////
#if CURVE_ON > 0 
// log数据加入
uint8_t curv_data_append(struct Curv_Item curvAppend){ 
    if(Curv_Saved_Sum > 1){ 
			  if(curvAppend.occTime - writeCurvData[Curv_Saved_Sum - 1].curvData.occTime < 10 \
					  || writeCurvData[Curv_Saved_Sum - 1].curvData.occTime - curvAppend.occTime < 10) return 0;	
		}	
	  if(Curv_Saved_Sum >= Curv_Data_size){  
			  #if Nor_Flash > 0  
			  // 满了就保存：	      
		    flash_curv_write();  
			  // 保存好，就重新开启一页;  
			  Curv_Saved_Sum = 1;  
			  curv_sect_save_id++;  
			  if(curv_sect_save_id >= Total_CurvData_Sects) curv_sect_save_id = 0;  
			  writeData[FWD_CurvSavePageId_idx].intData = curv_sect_save_id;  
			  flash_write();        			
			  #else  
			  uint16_t i = 0;	  
				for(i = 0; i < Curv_Saved_Sum - 1; i++){						
						writeCurvData[i].curvData = writeCurvData[i + 1].curvData;  
				}	 
        #endif			
		} else {
			  Curv_Saved_Sum++;  
		}		
		writeCurvData[Curv_Saved_Sum - 1].curvData = curvAppend;
    return 1;		
}

// log数据打印出来
void printCurvDatas(){
	 uint16_t i = 0;	
	 #if Nor_Flash > 0
	 printf("CvDataS:%d,%d:\r\n",curv_sect_save_id, Curv_Saved_Sum);
   #else
	 printf("CvDataS:%d:\r\n", Curv_Saved_Sum);
   #endif	
	 for(i = 0; i < Curv_Saved_Sum; i++){
		  printf("[ %d ]:",writeCurvData[i].curvData.occTime); 
		  printf(" %d, ",writeCurvData[i].curvData.chgPwr);
		  #if UI_Meter_Method == Meter_GuageIC_RN8302B 
      printf(" %d, ",writeCurvData[i].curvData.chgBPwr); 
      printf(" %d, ",writeCurvData[i].curvData.chgCPwr);
		  #endif
      printf(" %d, ",writeCurvData[i].curvData.chgI); 
		  #if UI_Meter_Method == Meter_GuageIC_RN8302B
		  printf(" %d, ",writeCurvData[i].curvData.chgBI); 
		  printf(" %d, ",writeCurvData[i].curvData.chgCI); 
		  #endif
		  printf(" %d \r\n",writeCurvData[i].curvData.chgTmpr);
	 }
}

// 按页读取norflash中数据
#if Nor_Flash > 0
void printPageCurvDatas(){
	 uint16_t i = 0;	
	 uint16_t curv_read_max = 0;
	 if(curv_sect_read_id == curv_sect_save_id){
			curv_read_max = Curv_Saved_Sum;			  
	 } else {
			curv_read_max = Curv_Data_size;			  
	 }
	 if(curv_read_max <= 0) return;
	 // 读取某页
	 flash_curvPage_read(curv_read_max);
	 // 打印
	 printf("==== CurvRead: %d  %d ==== \r\n", curv_read_max,curv_sect_read_id);  
	 for(i = 0; i < curv_read_max; i++){ 
			printf("[ %d ]:",readCurvData[i].curvData.occTime); 
		  printf(" %d, ",readCurvData[i].curvData.chgPwr);
		  #if UI_Meter_Method == Meter_GuageIC_RN8302B 
      printf(" %d, ",readCurvData[i].curvData.chgBPwr); 
      printf(" %d, ",readCurvData[i].curvData.chgCPwr);
		  #endif
      printf(" %d, ",readCurvData[i].curvData.chgI); 
		  #if UI_Meter_Method == Meter_GuageIC_RN8302B
		  printf(" %d, ",readCurvData[i].curvData.chgBI); 
		  printf(" %d, ",readCurvData[i].curvData.chgCI); 
		  #endif
		  printf(" %d \r\n",readCurvData[i].curvData.chgTmpr);
	 }
}
#endif // Nor_Flash > 0

#endif // #if CURVE_ON > 0


// 充电桩运行主策略：10ms一次;
void mTaskLed_strategy(){  
	  // 需要过启动时间；	
	  #ifdef SYS_DEBUG	  
	  printf("CP = %.2f, stat = %d - %d - %lld , %d, %d; u = %.2f, I = %.2f %d, T = %u %.2f %d %d, card1 = %d ,cpj = %d, lus = %d, Flt = %d  %u  %u  %u \n\r",\
	                     cp_data.CP_Value,cp_data.cp_state,cp_data.cp_state_treat,(system_time - cp_data.CP_idChg_Tm),  \
		                   cp_data.ADC_Data,cp_data.value_cope_id,UI_Data.U_RMS,UI_Data.I_RMS,PWM_Data.pwmDuty,TMP_BoardIn_R,\
	                     TMP_BoardIn,tmpr_CtrData.tmpr_state,faultOcc_IOvrRecv_counts,CarD1Param.CarD1_MarkNum,cp_data.CP_Jump_tms,\
	                     ledUsingStyle,faultCode,system_started,chg_selfCheck_complt,chgForbid);	
	  //printf("CP = %.2f, %d, %d, %d; u = %.2f, I = %.2f %d, card1 = %d; cum = %u,Flt = %d \n\r",cp_data.CP_Value,cp_data.cp_state,cp_data.cp_state_pre,cp_data.value_cope_id,UI_Data.U_RMS,UI_Data.I_RMS,PWM_Data.pwmDuty,CarD1Param.CarD1_MarkNum,chg_selfCheck_complt,faultCode);	
	  //printf("CP = %.2f, %d, %d, %d %d; u = %.2f, I = %.2f %d, chg_stage = %d; cum = %u,Flt = %d \n\r",cp_data.CP_Value,cp_data.cp_state,cp_data.cp_state_pre,cp_data.value_cope_id,cp_data.cp_state_sub,UI_Data.U_RMS,UI_Data.I_RMS,PWM_Data.pwmDuty,chg_stage,chg_selfCheck_complt,faultCode);	
	  //printf(" %.2f  %u  %u \r\n",cp_data.CP_Value,cp_data.ADC_Data,cp_data.CP_Jump_tms);
	  //printf("  %u  \r\n", sizeof(resv_data));
	  #endif
	
	  #if RTC_ON > 0
		getTimestampRTC();
		#endif
	  if(system_time - led_startUp_TmRecode > (ledStartUpHoldDarkTime + ledStartUpBlinkTime)){
			  system_started = 1;
			  // 开始亮灯策略：    
        faultCode = getFaultCode(mTask_Fault);
        if(faultCode == 0){
					  #ifdef UsingFreeRTOS
						mTask_Fault_using = 0;
						#endif
					  if(cp_data.cp_state != cp_data.cp_state_treat || main_update){
							  if(cp_data.cp_state == NO_PLUGGED){
									  #if (defined Using_LedCtrl_74HC595) && (I_rated_count == 1)
									  if(ledUsingStyle != 1){
											  ledUsingStyle = 1;
											  mTaskLedAllBlinkStop();
									      Led595_start(led595On_A);
                        //#ifdef Led7Pin_ABCDEFG
												//Led595_start(led595On_A);//0xFC
											  //#elif defined Led5Pin_ABCDE
											  //Led595_start(led595On_A); //0xF0最后3个没有接灯
											  //#endif
										}
									  #elif (defined Using_LedCtrl_MCUPin) && (I_rated_count == 1)
									  if(ledUsingStyle != 1){
											  ledUsingStyle = 1;
											  mTaskLedAllBlinkStop();
									      led_on(led_default);                        
										}
									  #elif (defined Using_LedCtrl_74HC595) && (I_rated_count > 1)
									  if(ledUsingStyle != I_rated_idx + 1){
											  ledUsingStyle = I_rated_idx + 1;
										    mTaskLedAllBlinkStop();
                        Led595_start(Led595_List[I_rated_idx]);												  
										}
									  #elif CHGR_panel_Sel == CHGR_panel_B26 && (I_rated_count > 1)
										if(ledUsingStyle != I_rated_idx + 1){
											  ledUsingStyle = I_rated_idx + 1;
										    mTaskLedAllBlinkStop();	
                        led_on(Led_idx_List[I_rated_idx]);	
										}
									  #endif
								}else if(cp_data.cp_state == PLUGGED){
									  if(cp_data.cp_state_sub == CHG_Fini || chg_stage == CHG_FULL){
												// 充电结束的灯效果
												if(ledUsingStyle != I_rated_count * 3 + I_rated_idx + 1){
														ledUsingStyle = I_rated_count * 3 + I_rated_idx + 1;											
														#ifdef Using_LedCtrl_74HC595
														mTaskLedAllBlinkStop();
														Led595_start(led595AllOn); 
														#elif defined Using_LedCtrl_MCUPin
														mTaskLedAllBlinkStop();
														led_on(Led_All);
														#endif
												}								
										}	else {
											  #if (defined Using_LedCtrl_74HC595) && (I_rated_count == 1)
												if(ledUsingStyle != I_rated_count + I_rated_idx + 1){
														ledUsingStyle = I_rated_count + I_rated_idx + 1;
														mTaskLedAllBlinkStop();
														Led595_start(led595AllOn);
												}
												#elif (defined Using_LedCtrl_74HC595) && (I_rated_count > 1)
												if(ledUsingStyle != I_rated_count + I_rated_idx + 1){
														ledUsingStyle = I_rated_count + I_rated_idx + 1;
														mTaskLedAllBlinkStop();
														Led595_bits = led595AllOn;
														Led_bits = 0x00;
														ledBlinkTms = 0;
														ledBlinkIntv[0] = 1000;
														ledBlinkIntv[1] = 0;
														mTaskLedBlinkStart();
												}										
												#elif CHGR_panel_Sel == CHGR_panel_B26 && (I_rated_count > 1)
												uint8_t refreshLed = 0;  
												if(ledUsingStyle != I_rated_count + I_rated_idx + 1){	
														ledUsingStyle = I_rated_count + I_rated_idx + 1;
														refreshLed = 1;	
														Led_bits = Led_idx_List[I_rated_idx];
													  LedOff_bits = Led_bits;
												}
												if(refreshLed){
														ledBlinkTms = 0;
														ledBlinkIntv[0] = 1000;
														ledBlinkIntv[1] = 0;												
														mTaskLedAllBlinkStop();
														mTaskLedBlinkStart();
												}
												#elif CHGR_panel_Sel == CHGR_panel_B26 && (I_rated_count == 1)
												uint8_t refreshLed = 0;  
												if(ledUsingStyle != I_rated_count + 1){
														ledUsingStyle = I_rated_count + 1;
														mTaskLedAllBlinkStop();
													  refreshLed = 1;	
														Led_bits = led_default;
													  LedOff_bits = Led_bits;	
												}
												if(refreshLed){
														ledBlinkTms = 0;
														ledBlinkIntv[0] = 1000;
														ledBlinkIntv[1] = 0;												
														mTaskLedAllBlinkStop();
														mTaskLedBlinkStart();
												}
												#endif											  
										}                    										
								}else if(cp_data.cp_state == BE_CHARGING){
									  #ifdef LedCtrl_Rolling 
									  if(ledUsingStyle != I_rated_count * 2 + I_rated_idx + 1){
												ledUsingStyle = I_rated_count * 2 + I_rated_idx + 1;
											  #ifdef Using_LedCtrl_MCUPin
												ledBlinkIntv[0] = 300;
											  #else
											  ledBlinkIntv[0] = 100;
										    #endif
											  mTaskLedAllBlinkStop();
										    mTaskLedRollStart();		
										}									
										#elif I_rated_count > 1
												uint8_t refreshLed = 0;
												#ifdef Using_LedCtrl_MCUPin
												//Led595_bits = 0xff;	
												if(ledUsingStyle != I_rated_count * 2 + I_rated_idx + 1){	
														ledUsingStyle = I_rated_count * 2 + I_rated_idx + 1;
														refreshLed = 1;
														Led_bits = Led_idx_List[I_rated_idx];
													  LedOff_bits = Led_bits;
												}		
												#elif (defined Using_LedCtrl_74HC595)
												//Led_bits = 0;										
												if(ledUsingStyle != I_rated_count * 2 + I_rated_idx + 1){
														ledUsingStyle = I_rated_count * 2 + I_rated_idx + 1;
													  refreshLed = 1;
														Led595_bits = Led595_List[I_rated_idx];
                            Led_bits = 0x00;													
												}	
												#endif
												if(refreshLed){
														ledBlinkTms = 0;
														ledBlinkIntv[0] = 600;
														ledBlinkIntv[1] = 0;
													  mTaskLedAllBlinkStop();
														mTaskLedBlinkStart();
												}
										#endif
								} 						
								cp_data.cp_state_treat = cp_data.cp_state; 
                main_update = 0;								
						}	
				} else {
					  uint8_t faultCodeBlink = faultCode;
					  chg_stage = CHG_ERROR;
					  #ifdef SYS_DEBUG
					  // printf("mTaskLed_strategy %d,  %d, %d\n",faultCode,faultCodeUsingLed,main_update);
					  #endif
					  if(faultCode != faultCodeUsingLed || main_update){
							  uint8_t refreshLed = 0;
							  //if(faultCodeBlink > Istate_adjust){
									  //faultCodeBlink = Istate_adjust;
								//}			
                #ifdef SYS_DEBUG
					      // printf(" Fault Led  %d,  %d, %d\n",faultCode,faultCodeUsingLed,main_update);
					      #endif								
							  // 有错误时的闪灯；                
								#if defined Using_LedCtrl_MCUPin
                if(ledUsingStyle != I_rated_count * 4 + I_rated_idx + 2){
										ledUsingStyle = I_rated_count * 4 + I_rated_idx + 2;
										refreshLed = 1;	
										Led_bits   = Led_All;
									  #if I_rated_count > 1
                    //LedOff_bits = Led_idx_List[I_rated_idx];	
                    #else
									  //LedOff_bits = led595On_A;	
									  #endif
								    LedOff_bits = Led_All;
								}	
								//#elif CHGR_panel_Sel == CHGR_panel_B20 || CHGR_panel_Sel == CHGR_panel_B14
								#elif defined Using_LedCtrl_74HC595
								if(ledUsingStyle != I_rated_count * 4 + I_rated_idx + 2){
									  ledUsingStyle = I_rated_count * 4 + I_rated_idx + 2;
									  refreshLed = 1;
									  Led_bits = BL_PinId;
								    Led595_bits = led595AllOff;
								}
								#endif
                if(refreshLed){
									  ledBlinkTms = faultCodeBlink;
										ledBlinkIntv[0] = 400;
										ledBlinkIntv[1] = 2000;
									  mTaskLedAllBlinkStop();
										mTaskLedBlinkStart();
								}									
						}
            main_update = 0;			
				}
        faultCodeUsingLed = faultCode;
		}	
}

// 充电策略
void mTaskCharge_strategy(){
	  #if RTC_ON > 0
		getTimestampRTC();
		#endif
	  faultCode = getFaultCode(mTask_Fault);
	  if(faultCode == 0 && system_started > 0){			  
			  if(cp_data.cp_state == NO_PLUGGED){  // 12V 
					  // PWM设为高电平：
						PWM_Duty_Set(DUTY_CYCLE_stop);
						// 关闭继电器
						Rly_off();	
						#ifdef SYS_DEBUG
						//printf("Rly_off cp_data.cp_state == NO_PLUGGED \r\n");
						#endif			
        }else if(cp_data.cp_state == PLUGGED){
					  // 9V时发送正常的PWM波：
						PWM_Duty_Set(PWM_Data.ratedDuty);
						// 关闭继电器
						Rly_off();
						#ifdef SYS_DEBUG										
						//printf("Rly_off cp_data.cp_state == PLUGGED  \r\n");	
						#endif
				}else if(cp_data.cp_state == BE_CHARGING){ // 6V 
					  #if Non_Plug_And_Charge > 0			  
						if(startChgExternalReason.chargeControl == 0) return;
						#elif PlugCharge_And_Resv
						if(resv_data.resv_time[0] > 1 && startChgExternalReason.chargeControl == 0) return;
						if(chg_stage == CHG_STOP || chg_stage == CHG_FULL) return;
						#endif	
					  PWM_Duty_Set(PWM_Data.ratedDuty);					  
					  if(chgForbid == 0){			
								if(Rly_status != 1 && chg_selfCheck_complt == chg_selfCheck_SUM){
										// 开启充电
										#if volt_zero_crossing > 0
										rly_on_mark  = 1;
										#else
										Rly_on();
										#endif
								}	
						}
            // 打印输出：
						#ifdef SYS_DEBUG
						//printf("Rly_on  cp_data.cp_state == BE_CHARGING \r\n");
						#endif 									
				} else {   // CP错误
					  PWM_Duty_Set(DUTY_CYCLE_stop);
					  // 关闭继电器
						Rly_off();	
				}
		}
}

// 充电桩错误策略：
uint8_t mTaskFault_strategy(){
	  uint8_t retValue = 0;
	  #ifdef SYS_DEBUG
	  //printf(" mTask_Fault = %x %x %d %d %d %d %d\n",mTask_Fault,mTask_Fault_using,fault_update,faultCode,faultCodeUsingErr,chgForbid,ledUsingStyle);
    //printf(" mTask_Fault = %x %d %d %d %d %lld\r\n",mTask_Fault,faultCode,faultCodeUsingErr,chgForbid,leakData.leak_test_init_step,system_time - leakData.leakSelfTest_start_tm);
	  #endif
    if(mTask_Fault != 0 && (mTask_Fault != mTask_Fault_using || fault_update)){
			  bool isRecoverFault = false;
			  faultCode = getFaultCode(mTask_Fault);
			  isRecoverFault = faultCode == low_voltage || faultCode == over_voltage || faultCode == PE_protection;
				isRecoverFault = isRecoverFault || faultCode == over_current || faultCode == over_tempr;
				// 异常处理：
				if(isRecoverFault){
						if(chgForbid == 0){
								// 有禁止充电的，恢复任务就不能执行；
								// 带恢复的错误处理：恢复任务Id越小，优先级越高，不会被覆盖。								
                // 断电操作
								PWM_Duty_Set(DUTY_CYCLE_stop);
								Rly_off();
								#ifdef SYS_DEBUG
								// printf("Rly_off mTask_Fault = %d \r\n",faultCode);
								#endif									
								// 保护时间和恢复时间设置;[在保护时间内，不许恢复；在恢复时间内不许进行错误检测和报错]
                if(faultCode == PE_protection && (faultCode < faultCodeUsingErr || faultCodeUsingErr == 0)){
										fault_recvr_intv = PE_Recover_tmEnd;
								    // 电压恢复:过压或欠压;
									  // 恢复启动;
										#ifndef UsingFreeRTOS
									  #if RTC_ON > 0
										getTimestampRTC();
										#endif
										fault_recover_tm = system_time;
									  #else
									  retValue = 1;
										#endif
								#if Volt_Protection > 0
								}else if((faultCode == low_voltage || faultCode == over_voltage) && (faultCode < faultCodeUsingErr || faultCodeUsingErr == 0)){
										fault_recvr_intv = U_Recv_TmEnd;
									  // 恢复启动;
										#ifndef UsingFreeRTOS
									  #if RTC_ON > 0
										getTimestampRTC();
										#endif
										fault_recover_tm = system_time;
									  #else
									  retValue = 1;
										#endif
								#endif		
								}								
						}			  
				}else if(faultCode == Istate_adjust || faultCode == tmpr_adjust_err){
						 // 电流调整的处理:同时发生时，错误id值越小，越优先。
						 // 电流调整
					   if(faultCode == Istate_adjust){
							  ///////////////   电流调整操作  //////////////////
								// 正在充电：调整充电电流; 10分钟调整一次;
								uint16_t ratedDutyTmp = PWM_Data.pwmDuty - Duty_Adj_Step; 
								PWM_Data.pwmDuty = ratedDutyTmp > DUTY_CYCLE_MIN ? ratedDutyTmp : DUTY_CYCLE_MIN; 
								PWM_Duty_Set(PWM_Data.pwmDuty);
							  // 恢复状态，方便下次刷新
							  #ifndef UsingFreeRTOS
							  #if RTC_ON > 0
								getTimestampRTC();
								#endif
								fault_recover_tm = system_time;
							  #else
							  retValue = 1; 
								#endif 
							  fault_recvr_intv = IAdj_intv;
						}else if(faultCode == tmpr_adjust_err){
							  if(faultOcc_TmprAdj_counts < tmpr_adj_tms){
									  uint16_t ratedDutyTmp = PWM_Data.pwmDuty / 2;
										PWM_Data.pwmDuty = ratedDutyTmp > DUTY_CYCLE_MIN ? ratedDutyTmp : DUTY_CYCLE_MIN; 
										PWM_Duty_Set(PWM_Data.pwmDuty);
										faultOcc_TmprAdj_counts++;
								}
						}
				} else {
						// 不带恢复的错误处理：优先级最高，无需考虑优先级，直接停充电。
						chgForbid = faultCode;
					  // 停充处理
						PWM_Duty_Set(DUTY_CYCLE_stop);
						Rly_off();
						#ifdef SYS_DEBUG
						// printf("Rly_off mTask_Fault = %d \r\n",faultCode);	
						#endif					
					  #ifdef SYS_DEBUG
						// printf(" mTaskFault_strategy chgForbid = %d  \r\n",chgForbid);  	 		
            #endif					
				}
				// 记录下异常到日志中：
				// 错误事件
				#if LOG_ON > 0
					#if RTC_ON > 0
						getTimestampRTC();
					#endif
					log_temp.occTime  = system_time / 1000;
					log_temp.logGrade = Log_Error;               // 错误级别;
					log_temp.logEvent = faultCode;               // 错误编号;
					log_temp.logEvtData = 0;                     // 错误数据;
					if(log_data_append(log_temp)){
						  writeData[FWD_LogsSize_idx].intData = (uint32_t)Log_Saved_Sum; // 更新Log总数
							// 数据保存
							flash_write();
							flash_log_write();
					}					
				#endif
				faultCodeUsingErr = faultCode;
		}
		mTask_Fault_using = mTask_Fault;
		fault_update = 0;	
		return retValue;
}

void UpBoard_DisplayUpdate(void)
{
//	UpBoard_Test();
	Up_Screen_Updata();
}


#endif //回应头部：#ifndef __BoardWork_C  

